Android开发中使用七牛云存储进行图片上传下载

  Android开发中的图片存储本来就是比较耗时耗地的事情,而使用第三方的七牛云,便可以很好的解决这些后顾之忧,最近我也是在学习七牛的SDK,将使用过程在这记录下来,方便以后使用。

        

  先说一下七牛云的存储原理,上面这幅图片是官方给出的原理图,表述当然比较清晰了。可以看出,要进行图片上传的话可以分为五大步:

    1. 客户端用户登录到APP的账号系统里面;

    2. 客户端上传文件之前,需要向业务服务器申请七牛的上传凭证,这个凭证由业务服务器使用七牛提供的服务端SDK生成;

    3. 客户端使用七牛提供的客户端SDK,调用上传方法上传文件,上传方法中必须有上传凭证和文件内容(由于七牛允许大小为0的文件,所以文件上传之前,建议检查文件大小。如果业务不允许文件大小为0,那么需要自行检测下);

    4. 客户端文件上传到七牛之后,可选的操作是七牛回调业务服务器,(即七牛把文件相关的信息发送POST请求到上传策略里面指定的回调地址);

    5. 业务服务器回复七牛的回调请求,给出JSON格式的回复内容(必须是JSON格式的回复),这个回复内容将被七牛转发给客户端;

  好了,七牛云的运作原理搞清楚了,仔细理解一下也不是很麻烦嘛,下面我们来开始整合操作吧。

一、下载官方SDK

  参照七牛云官网(http://www.qiniu.com/?utm_campaign=baiduSEM&utm_source=baiduSEM&utm_medium=baiduSEM&utm_content=baiduSEM)下载指定SDK,其实根据官方提供的Maven地址下载就好了,在下载最新版QiniuSDK之后,是不是就可以忙着copy开发文档中的相应代码了?

  千万别急,除了依赖qiniu-android-sdk,还要依赖happy-dns,okhttp,android-async-http,这样一共是四个依赖包。这里说个小技巧,如果嫌下载那些东西麻烦,可以将官方Demo下载下来,然后将里边的依赖包全部放到自己的项目里,当然这样做的前提是你要分得清哪些是哪些。

二、清单文件添加权限

  注意:如果使用Android5.0及其以上版本,权限是要在代码中申请的。

1 <uses-permission android:name="android.permission.INTERNET"/>
2 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

三、定义变量

  在写上传下载代码前,我们需要先定义以下几个变量。

 1     private TextView title;  //显示上传结果
 2     private ImageView image;  //显示下载的图片内容
 3     private ProgressDialog progressDialog;  //上传进度提示框
 4     private boolean isProgressCancel;  //网络请求过程中是否取消上传或下载
 5     private UploadManager uploadManager;  //七牛SDK的上传管理者
 6     private UploadOptions uploadOptions;  //七牛SDK的上传选项
 7     private MyUpCompletionHandler mHandler;  //七牛SDK的上传返回监听
 8     private UpProgressHandler upProgressHandler;  //七牛SDK的上传进度监听
 9     private UpCancellationSignal upCancellationSignal;  //七牛SDK的上传过程取消监听
10     private final static String TOKEN_URL = "http://xxx.xxx.xxx/x/";  //服务器请求token的网址
11     private String uptoken;  //服务器请求Token值
12     private String upKey;  //上传文件的Key值
13     private byte[] upLoadData;  //上传的文件

四、上传图片

  七牛服务器可以上传的有三种类型,包括byte[]类型的图片,String类型的文件路径,File类型的文件;

(一)从服务器请求token

 1     private void getTokenFromService() {
 2         //模拟从服务端获取uptoken
 3         uptoken = "12343232313123";
 4         SyncHttpClient client = new SyncHttpClient();
 5         client.get(TOKEN_URL, new TextHttpResponseHandler() {
 6             @Override
 7             public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
 8                 Log.e("Error", "onFailure: 服务器请求Token失败");
 9             }
10
11             @Override
12             public void onSuccess(int statusCode, Header[] headers, String responseString) {
13                 try {
14                     JSONObject jsonObject = new JSONObject(responseString);
15                     //解析得到的Json串,获取token值
16                     uptoken = jsonObject.getString("token");
17                 } catch (JSONException e) {
18                     e.printStackTrace();
19                 }
20             }
21         });
22     }

(二)初始化上传参数

 1     private void initData() {
 2         getTokenFromService();
 3         upKey = getPicture();
 4         uploadManager = new UploadManager();
 5         upProgressHandler = new UpProgressHandler() {
 6             /**
 7              * @param key 上传时的upKey;
 8              * @param percent 上传进度;
 9              */
10             @Override
11             public void progress(String key, double percent) {
12                 progressDialog.setProgress((int) (upLoadData.length * percent));
13             }
14         };
15         upCancellationSignal = new UpCancellationSignal() {
16             @Override
17             public boolean isCancelled() {
18                 return isProgressCancel;
19             }
20         };
21         //定义数据或文件上传时的可选项
22         uploadOptions = new UploadOptions(
23                 null,  //扩展参数,以<code>x:</code>开头的用户自定义参数
24                 "mime_type",  //指定上传文件的MimeType
25                 true,  //是否启用上传内容crc32校验
26                 upProgressHandler,  //上传内容进度处理
27                 upCancellationSignal  //取消上传信号
28         );
29         mHandler = new MyUpCompletionHandler();
30     }

(三)启动异步线程,上传图片文件

 1     public void clickPost(View view) {
 2         if (TextUtils.isEmpty(uptoken)) {
 3             Toast.makeText(MainActivity.this, "正在从网络获取Token值,请稍后...", Toast.LENGTH_SHORT).show();
 4             return;
 5         }
 6         new Thread(new Runnable() {
 7             @Override
 8             public void run() {
 9                 progressDialog.setMax(upLoadData.length);
10                 progressDialog.show();
11                 uploadManager.put(upLoadData, upKey, uptoken, mHandler, uploadOptions);
12             }
13         });
14     }

五、下载图片

  该 SDK 并未提供下载文件相关的功能接口,因为文件下载是一个标准的 HTTP GET 过程。开发者只需理解资源 URI 的组成格式即可非常方便的构建资源 URI,并在必要的时候加上下载凭证,即可使用 HTTP GET 请求获取相应资源。

  上段斜体是从QiniuSDK官网的指导文档中复制的,所以下载方式比较简单。

 1     public void clickDown(View view) {
 2         //图片上传到七牛之后,
 3         // 默认会将文件的hash和key(文件的文件名)响应回来,
 4         // 然后在空间设置->域名设置里,找到空间域名,
 5         // 通过http://空间域名/key的形式,拿到文件的url。
 6         String fileName = "xxx.xxx.xx/xx";
 7         String downUrl = "http://" + fileName + "/" + upKey;
 8         SyncHttpClient client = new SyncHttpClient();
 9         client.get(downUrl, new BinaryHttpResponseHandler() {
10             @Override
11             public void onSuccess(int statusCode, Header[] headers, byte[] binaryData) {
12                 if (binaryData != null) {
13                     image.setImageBitmap(BitmapFactory.decodeByteArray(binaryData, 0, binaryData.length));
14                 }
15             }
16             @Override
17             public void onFailure(int statusCode, Header[] headers, byte[] binaryData, Throwable error) {
18                 Log.e("Error", "onFailure: 图片下载失败" );
19             }
20         });
21     }

六、文档总结

  有时候看一百遍文字介绍,也不如读一遍Fuck Code,所以我还是把涉及的文件源码也copy过来一份,以后也方便看了。

(一)MainActivity.class

  1 package com.example.administrator;
  2
  3 import android.app.ProgressDialog;
  4 import android.content.DialogInterface;
  5 import android.graphics.BitmapFactory;
  6 import android.os.Bundle;
  7 import android.support.v7.app.AppCompatActivity;
  8 import android.text.TextUtils;
  9 import android.util.Log;
 10 import android.view.View;
 11 import android.widget.ImageView;
 12 import android.widget.TextView;
 13 import android.widget.Toast;
 14
 15 import com.example.administrator.myqiniudemo.R;
 16 import com.loopj.android.http.BinaryHttpResponseHandler;
 17 import com.loopj.android.http.SyncHttpClient;
 18 import com.loopj.android.http.TextHttpResponseHandler;
 19 import com.qiniu.android.http.ResponseInfo;
 20 import com.qiniu.android.storage.UpCancellationSignal;
 21 import com.qiniu.android.storage.UpCompletionHandler;
 22 import com.qiniu.android.storage.UpProgressHandler;
 23 import com.qiniu.android.storage.UploadManager;
 24 import com.qiniu.android.storage.UploadOptions;
 25
 26 import org.json.JSONException;
 27 import org.json.JSONObject;
 28
 29 import cz.msebera.android.httpclient.Header;
 30
 31 public class MainActivity extends AppCompatActivity {
 32
 33     private TextView title;  //显示上传结果
 34     private ImageView image;  //显示下载的图片内容
 35     private ProgressDialog progressDialog;  //上传进度提示框
 36     private boolean isProgressCancel;  //网络请求过程中是否取消上传或下载
 37     private UploadManager uploadManager;  //七牛SDK的上传管理者
 38     private UploadOptions uploadOptions;  //七牛SDK的上传选项
 39     private MyUpCompletionHandler mHandler;  //七牛SDK的上传返回监听
 40     private UpProgressHandler upProgressHandler;  //七牛SDK的上传进度监听
 41     private UpCancellationSignal upCancellationSignal;  //七牛SDK的上传过程取消监听
 42     private final static String TOKEN_URL = "http://xxx.xxx.xxx/x/";  //服务器请求token的网址
 43     private String uptoken;  //服务器请求Token值
 44     private String upKey;  //上传文件的Key值
 45     private byte[] upLoadData;  //上传的文件
 46
 47     @Override
 48     protected void onCreate(Bundle savedInstanceState) {
 49         super.onCreate(savedInstanceState);
 50         setContentView(R.layout.activity_main);
 51         initView();
 52         initData();
 53     }
 54
 55     private void initData() {
 56         getTokenFromService();
 57         upKey = getPicture();
 58         uploadManager = new UploadManager();
 59         upProgressHandler = new UpProgressHandler() {
 60             /**
 61              * @param key 上传时的upKey;
 62              * @param percent 上传进度;
 63              */
 64             @Override
 65             public void progress(String key, double percent) {
 66                 progressDialog.setProgress((int) (upLoadData.length * percent));
 67             }
 68         };
 69         upCancellationSignal = new UpCancellationSignal() {
 70             @Override
 71             public boolean isCancelled() {
 72                 return isProgressCancel;
 73             }
 74         };
 75         //定义数据或文件上传时的可选项
 76         uploadOptions = new UploadOptions(
 77                 null,  //扩展参数,以<code>x:</code>开头的用户自定义参数
 78                 "mime_type",  //指定上传文件的MimeType
 79                 true,  //是否启用上传内容crc32校验
 80                 upProgressHandler,  //上传内容进度处理
 81                 upCancellationSignal  //取消上传信号
 82         );
 83         mHandler = new MyUpCompletionHandler();
 84     }
 85
 86     private String getPicture() {
 87         //模拟上传图片的byte数组,并返回文件名
 88         upLoadData = new byte[]{1, 2, 3, 1, 2, 3, 12, 3, 4, 2, 1, 2};
 89         return "upload.txt";
 90     }
 91
 92     private void getTokenFromService() {
 93         //模拟从服务端获取uptoken
 94         uptoken = "12343232313123";
 95         SyncHttpClient client = new SyncHttpClient();
 96         client.get(TOKEN_URL, new TextHttpResponseHandler() {
 97             @Override
 98             public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
 99                 Log.e("Error", "onFailure: 服务器请求Token失败");
100             }
101
102             @Override
103             public void onSuccess(int statusCode, Header[] headers, String responseString) {
104                 try {
105                     JSONObject jsonObject = new JSONObject(responseString);
106                     //解析得到的Json串,获取token值
107                     uptoken = jsonObject.getString("token");
108                 } catch (JSONException e) {
109                     e.printStackTrace();
110                 }
111             }
112         });
113     }
114
115     private void initView() {
116         title = (TextView) findViewById(R.id.title);
117         image = (ImageView) findViewById(R.id.image);
118         initProgressBar();
119     }
120
121     private void initProgressBar() {
122         progressDialog = new ProgressDialog(MainActivity.this);
123         progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
124         progressDialog.setTitle("进度提示");
125         progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
126             @Override
127             public void onClick(DialogInterface dialog, int which) {
128                 isProgressCancel = true;
129             }
130         });
131     }
132
133     /**
134      * 点击按钮,开始文件上传
135      *
136      * @param view
137      */
138     public void clickPost(View view) {
139         if (TextUtils.isEmpty(uptoken)) {
140             Toast.makeText(MainActivity.this, "正在从网络获取Token值,请稍后...", Toast.LENGTH_SHORT).show();
141             return;
142         }
143         new Thread(new Runnable() {
144             @Override
145             public void run() {
146                 progressDialog.setMax(upLoadData.length);
147                 progressDialog.show();
148                 uploadManager.put(upLoadData, upKey, uptoken, mHandler, uploadOptions);
149             }
150         });
151     }
152
153     /**
154      * 点击按钮,开始文件下载
155      *
156      * @param view
157      */
158     public void clickDown(View view) {
159         //图片上传到七牛之后,
160         // 默认会将文件的hash和key(文件的文件名)响应回来,
161         // 然后在空间设置->域名设置里,找到空间域名,
162         // 通过http://空间域名/key的形式,拿到文件的url。
163         String fileName = "xxx.xxx.xx/xx";
164         String downUrl = "http://" + fileName + "/" + upKey;
165         SyncHttpClient client = new SyncHttpClient();
166         client.get(downUrl, new BinaryHttpResponseHandler() {
167             @Override
168             public void onSuccess(int statusCode, Header[] headers, byte[] binaryData) {
169                 if (binaryData != null) {
170                     image.setImageBitmap(BitmapFactory.decodeByteArray(binaryData, 0, binaryData.length));
171                 }
172             }
173             @Override
174             public void onFailure(int statusCode, Header[] headers, byte[] binaryData, Throwable error) {
175                 Log.e("Error", "onFailure: 图片下载失败" );
176             }
177         });
178     }
179
180     /**
181      * 自定义上传完成监听类
182      * 实现QiniuSDK中的UpCompletionHandler接口
183      */
184     public class MyUpCompletionHandler implements UpCompletionHandler {
185         /**
186          * @param key      上传时的upKey;
187          * @param info     Json串表示的上传信息,包括使用版本,请求状态,请求Id等信息;
188          * @param response Json串表示的文件信息,包括文件Hash码,文件Mime类型,文件大小等信息;
189          */
190         @Override
191         public void complete(String key, ResponseInfo info, JSONObject response) {
192             progressDialog.dismiss();
193             title.setText(key + "!\n" + info + "!\n" + response + "!");
194         }
195     }
196 }

(二)activity_main.xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout
 3     android:orientation="vertical"
 4     xmlns:android="http://schemas.android.com/apk/res/android"
 5     xmlns:tools="http://schemas.android.com/tools"
 6     android:layout_width="match_parent"
 7     android:layout_height="match_parent"
 8     android:gravity="center_horizontal"
 9     tools:context="com.example.administrator.myqiniudemo.MainActivity">
10
11     <TextView
12         android:id="@+id/title"
13         android:layout_width="wrap_content"
14         android:layout_height="wrap_content"
15         android:text="Hello Qiniu!"/>
16     <Button
17         android:layout_width="wrap_content"
18         android:layout_height="wrap_content"
19         android:text="上传图片"
20         android:onClick="clickPost"
21         />
22     <Button
23         android:layout_width="wrap_content"
24         android:layout_height="wrap_content"
25         android:text="下载图片"
26         android:onClick="clickDown"
27         />
28     <ImageView
29         android:id="@+id/image"
30         android:layout_width="match_parent"
31         android:layout_height="match_parent"/>
32 </LinearLayout>

时间: 2024-10-08 13:56:24

Android开发中使用七牛云存储进行图片上传下载的相关文章

CKeditor七牛云JS SDK前端上传插件修改

七牛云官方有放出JS SDK,没有我想使用的CKeditor前端上传插件,所以结合七牛官方的Javascript SDK对CKeditor做了一些修改使它能够直接上传到七牛云,又同时保留了上传到本地服务的接口. 优点和缺点1.在前端上传到七牛云,不消耗服务器带宽和流量.空间.2.保留了CKeditor上传到自己服务器的能力.3.支持拖拽和剪切板黏贴图片上传(因为是保存为png格式,建议只黏贴色彩单调的图片,要不然图片会很大,浪费流量).4.拖拽和剪切板黏贴图片.不支持4M以上的文件,因为没有分块

C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件)

原文:C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件) 微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C#微信公众号开发系列教程四(接收普通消息) C#微信公众号开发系列教程五(接收事件推送与消息排重) C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件) 第四,第五章已经讲了怎么处理用户发送的消息,本章就来讲讲怎么响应用户的

如何在WordPress中使用七牛云存储

序:七牛云存储可以方便的将网站的图片等数据镜像到七牛云存储的空间,直接从云端将数据返回给用户.这样可以大大节省网站的空间,提升网站的访问速度. 真正显示一键实现WordPress博客静态文件CDN加速.下面主要介绍一下WordPress中七牛云存储插件的使用. 一.申请七牛云存储的账号 首先需要申请七牛云存储的账号,申请好后,点击创建空间,选择空间类型为公开空间,提交 二.配置空间 配置空间,点击一键加速网站. 镜像源填写自己网站域名.确认加速. 这里的robots.txt配置文件内容为: #

android开发中的5种存储数据方式

数据存储在开发中是使用最频繁的,根据不同的情况选择不同的存储数据方式对于提高开发效率很有帮助.下面笔者在主要介绍Android平台中实现数据存储的5种方式. 1.使用SharedPreferences存储数据 SharedPreferences是Android平台上一个轻量级的存储类,主要是保存一些常用的配置比如窗口状态,一般在Activity中 重载窗口状态onSaveInstance State保存一般使用SharedPreferences完成,它提供了Android平台常规的Long长 整

PHP使用七牛云存储之图片的上传、下载、303重定向教程,CI框架实例

网上关于七牛云存储的教程除了官网上的API文档,其他的资料太少了.研究了下API之后,现在已经能实现图片的上传和下载及上传之后的重定向. 首先本篇文章实现的功能如下: 1.利用表单上传功能,用户可以点击选择文件按钮,选择本地的一个文件,同时设定上传的图片的名称,点击上传按钮可以上传并存储到七牛云存储. 2.在点击上传时会检测文件的后缀名,限制为jpg和png格式存储. 3.上传成功后跳转到自己设定的一个URL,并传回文件信息,如文件名.而不是显示七牛白花花的json显示页面. 好啦,那我们开始吧

微信小程序基于腾讯云对象存储的图片上传

在使用腾讯云对象存储之前,公司一直使用的是传统的FTP的上传模式,而随着用户量的不断增加,FTP所暴露出来的问题也越来越多,1.传输效率低,上传速度慢.2.时常有上传其他文件来攻击服务器,安全上得不到保障.所以我们在经过慎重考虑觉得使用第三方的云存储服务. 在最开始的时候我们在腾讯云与阿里云中选择,最终我们选择腾讯云,腾讯云在文件上传用时方面的性能比较突出,文件越大表现越好:在下载用时方面表现略优于阿里云:文件删除用时方面总体速度略逊于,但在不同大小文件删除用时上都比较稳定.当然这与我们主要用于

JSP+Servlet中使用jspsmartupload.jar进行图片上传下载

JSP+Servlet中使用cos.jar进行图片上传 upload.jsp <form action="FileServlet" method="post" enctype="multipart/form-data"> <input type="file" name="myfile"> <input type="text" name="cmt&q

MVC4中基于bootstrap和HTML5的图片上传Jquery自定义控件

场景:mvc4中上传图片,批量上传,上传前浏览,操作.图片进度条. 解决:自定义jquery控件 没有解决:非图片上传时,会有浏览样式的问题; 解决方案; 1.样式 – bootstrap 的css和图标与metro-ui-css的部分css 2.js 自定义控件 3.后台 mvc4 ------------------------------------------------- 1. [class*=border-color] { border: 2px solid; } .border-c

Nodejs之MEAN栈开发(四)-- form验证及图片上传

这一节增加推荐图书的提交和删除功能,来学习node的form提交以及node的图片上传功能.开始之前需要源码同学可以先在git上fork:https://github.com/stoneniqiu/ReadingClub 一.form验证 MVC的form验证有三个地方可以做,第一道关就是前端提交之前,第二道关就是在数据保存之前,也就是在controller中做验证,第三道关就是数据保存的时候,也就是如果提交的数据模型不符合实体定义的约束,数据是无法保存的,这是最后一道防线.第一道关主要是依赖于