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及其以上版本,許可權是要在代碼中申請的。
<uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
三、定義變數
在寫上傳下載代碼前,我們需要先定義以下幾個變數。
private TextView title; //顯示上傳結果private ImageView image; //顯示下載的圖片內容private ProgressDialog progressDialog; //上傳進度提示框private boolean isProgressCancel; //網路請求過程中是否取消上傳或下載private UploadManager uploadManager; //七牛SDK的上傳管理者private UploadOptions uploadOptions; //七牛SDK的上傳選項private MyUpCompletionHandler mHandler; //七牛SDK的上傳返回監聽private UpProgressHandler upProgressHandler; //七牛SDK的上傳進度監聽private UpCancellationSignal upCancellationSignal; //七牛SDK的上傳過程取消監聽private final static String TOKEN_URL = "http://xxx.xxx.xxx/x/"; //伺服器請求token的網址private String uptoken; //伺服器請求Token值private String upKey; //上傳檔案的Key值private byte[] upLoadData; //上傳的檔案
四、上傳圖片
七牛伺服器可以上傳的有三種類型,包括byte[]類型的圖片,String類型的檔案路徑,File類型的檔案;
(一)從伺服器請求token
private void getTokenFromService() {//類比從服務端擷取uptokenuptoken = "12343232313123";SyncHttpClient client = new SyncHttpClient();client.get(TOKEN_URL, new TextHttpResponseHandler() {@Overridepublic void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {Log.e("Error", "onFailure: 伺服器請求Token失敗");}@Overridepublic void onSuccess(int statusCode, Header[] headers, String responseString) {try {JSONObject jsonObject = new JSONObject(responseString);//解析得到的Json串,擷取token值uptoken = jsonObject.getString("token");} catch (JSONException e) {e.printStackTrace();}}});}
(二)初始化上傳參數
private void initData() {getTokenFromService();upKey = getPicture();uploadManager = new UploadManager();upProgressHandler = new UpProgressHandler() {/*** @param key 上傳時的upKey;* @param percent 上傳進度;*/@Overridepublic void progress(String key, double percent) {progressDialog.setProgress((int) (upLoadData.length * percent));}};upCancellationSignal = new UpCancellationSignal() {@Overridepublic boolean isCancelled() {return isProgressCancel;}};//定義資料或檔案上傳時的可選項uploadOptions = new UploadOptions(null, //擴充參數,以<code>x:</code>開頭的使用者自訂參數"mime_type", //指定上傳檔案的MimeTypetrue, //是否啟用上傳內容crc32校正upProgressHandler, //上傳內容進度處理upCancellationSignal //取消上傳訊號);mHandler = new MyUpCompletionHandler();}
(三)啟動非同步線程,上傳圖片檔案
public void clickPost(View view) {if (TextUtils.isEmpty(uptoken)) {Toast.makeText(MainActivity.this, "正在從網路擷取Token值,請稍後...", Toast.LENGTH_SHORT).show();return;}new Thread(new Runnable() {@Overridepublic void run() {progressDialog.setMax(upLoadData.length);progressDialog.show();uploadManager.put(upLoadData, upKey, uptoken, mHandler, uploadOptions);}});}
五、下載圖片
該 SDK 並未提供下載檔案相關的功能介面,因為檔案下載是一個標準的 HTTP GET 過程。開發人員只需理解資源 URI 的組成格式即可非常方便的構建資源 URI,並在必要的時候加上下載憑證,即可使用 HTTP GET 請求擷取相應資源。
上段斜體是從QiniuSDK官網的指導文檔中複製的,所以下載方式比較簡單。
public void clickDown(View view) {//圖片上傳到七牛之後,// 預設會將檔案的hash和key(檔案的檔案名稱)響應回來,// 然後在空間設定->網域名稱設定裡,找到空間網域名稱,// 通過http://空間網域名稱/key的形式,拿到檔案的url。String fileName = "xxx.xxx.xx/xx";String downUrl = "http://" + fileName + "/" + upKey;SyncHttpClient client = new SyncHttpClient();client.get(downUrl, new BinaryHttpResponseHandler() {@Overridepublic void onSuccess(int statusCode, Header[] headers, byte[] binaryData) {if (binaryData != null) {image.setImageBitmap(BitmapFactory.decodeByteArray(binaryData, 0, binaryData.length));}}@Overridepublic void onFailure(int statusCode, Header[] headers, byte[] binaryData, Throwable error) {Log.e("Error", "onFailure: 圖片下載失敗" );}});}
六、文檔總結
有時候看一百遍文字介紹,也不如讀一遍Fuck Code,所以我還是把涉及的檔案源碼也copy過來一份,以後也方便看了。
(一)MainActivity.class
package com.example.administrator;import android.app.ProgressDialog;import android.content.DialogInterface;import android.graphics.BitmapFactory;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.text.TextUtils;import android.util.Log;import android.view.View;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;import com.example.administrator.myqiniudemo.R;import com.loopj.android.http.BinaryHttpResponseHandler;import com.loopj.android.http.SyncHttpClient;import com.loopj.android.http.TextHttpResponseHandler;import com.qiniu.android.http.ResponseInfo;import com.qiniu.android.storage.UpCancellationSignal;import com.qiniu.android.storage.UpCompletionHandler;import com.qiniu.android.storage.UpProgressHandler;import com.qiniu.android.storage.UploadManager;import com.qiniu.android.storage.UploadOptions;import org.json.JSONException;import org.json.JSONObject;import cz.msebera.android.httpclient.Header;public class MainActivity extends AppCompatActivity {private TextView title; //顯示上傳結果private ImageView image; //顯示下載的圖片內容private ProgressDialog progressDialog; //上傳進度提示框private boolean isProgressCancel; //網路請求過程中是否取消上傳或下載private UploadManager uploadManager; //七牛SDK的上傳管理者private UploadOptions uploadOptions; //七牛SDK的上傳選項private MyUpCompletionHandler mHandler; //七牛SDK的上傳返回監聽private UpProgressHandler upProgressHandler; //七牛SDK的上傳進度監聽private UpCancellationSignal upCancellationSignal; //七牛SDK的上傳過程取消監聽private final static String TOKEN_URL = "http://xxx.xxx.xxx/x/"; //伺服器請求token的網址private String uptoken; //伺服器請求Token值private String upKey; //上傳檔案的Key值private byte[] upLoadData; //上傳的檔案@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();initData();}private void initData() {getTokenFromService();upKey = getPicture();uploadManager = new UploadManager();upProgressHandler = new UpProgressHandler() {/*** @param key 上傳時的upKey;* @param percent 上傳進度;*/@Overridepublic void progress(String key, double percent) {progressDialog.setProgress((int) (upLoadData.length * percent));}};upCancellationSignal = new UpCancellationSignal() {@Overridepublic boolean isCancelled() {return isProgressCancel;}};//定義資料或檔案上傳時的可選項uploadOptions = new UploadOptions(null, //擴充參數,以<code>x:</code>開頭的使用者自訂參數"mime_type", //指定上傳檔案的MimeTypetrue, //是否啟用上傳內容crc32校正upProgressHandler, //上傳內容進度處理upCancellationSignal //取消上傳訊號);mHandler = new MyUpCompletionHandler();}private String getPicture() {//類比上傳圖片的byte數組,並返迴文件名upLoadData = new byte[]{1, 2, 3, 1, 2, 3, 12, 3, 4, 2, 1, 2};return "upload.txt";}private void getTokenFromService() {//類比從服務端擷取uptokenuptoken = "12343232313123";SyncHttpClient client = new SyncHttpClient();client.get(TOKEN_URL, new TextHttpResponseHandler() {@Overridepublic void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {Log.e("Error", "onFailure: 伺服器請求Token失敗");}@Overridepublic void onSuccess(int statusCode, Header[] headers, String responseString) {try {JSONObject jsonObject = new JSONObject(responseString);//解析得到的Json串,擷取token值uptoken = jsonObject.getString("token");} catch (JSONException e) {e.printStackTrace();}}});}private void initView() {title = (TextView) findViewById(R.id.title);image = (ImageView) findViewById(R.id.image);initProgressBar();}private void initProgressBar() {progressDialog = new ProgressDialog(MainActivity.this);progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);progressDialog.setTitle("進度提示");progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {isProgressCancel = true;}});}/*** 點擊按鈕,開始檔案上傳** @param view*/public void clickPost(View view) {if (TextUtils.isEmpty(uptoken)) {Toast.makeText(MainActivity.this, "正在從網路擷取Token值,請稍後...", Toast.LENGTH_SHORT).show();return;}new Thread(new Runnable() {@Overridepublic void run() {progressDialog.setMax(upLoadData.length);progressDialog.show();uploadManager.put(upLoadData, upKey, uptoken, mHandler, uploadOptions);}});}/*** 點擊按鈕,開始檔案下載** @param view*/public void clickDown(View view) {//圖片上傳到七牛之後,// 預設會將檔案的hash和key(檔案的檔案名稱)響應回來,// 然後在空間設定->網域名稱設定裡,找到空間網域名稱,// 通過http://空間網域名稱/key的形式,拿到檔案的url。String fileName = "xxx.xxx.xx/xx";String downUrl = "http://" + fileName + "/" + upKey;SyncHttpClient client = new SyncHttpClient();client.get(downUrl, new BinaryHttpResponseHandler() {@Overridepublic void onSuccess(int statusCode, Header[] headers, byte[] binaryData) {if (binaryData != null) {image.setImageBitmap(BitmapFactory.decodeByteArray(binaryData, 0, binaryData.length));}}@Overridepublic void onFailure(int statusCode, Header[] headers, byte[] binaryData, Throwable error) {Log.e("Error", "onFailure: 圖片下載失敗" );}});}/*** 自訂上傳完成監聽類* 實現QiniuSDK中的UpCompletionHandler介面*/public class MyUpCompletionHandler implements UpCompletionHandler {/*** @param key 上傳時的upKey;* @param info Json串表示的上傳資訊,包括使用版本,請求狀態,請求Id等資訊;* @param response Json串表示的檔案資訊,包括檔案Hash碼,檔案Mime類型,檔案大小等資訊;*/@Overridepublic void complete(String key, ResponseInfo info, JSONObject response) {progressDialog.dismiss();title.setText(key + "!\n" + info + "!\n" + response + "!");}}}
(二)activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayoutandroid:orientation="vertical"xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center_horizontal"tools:context="com.example.administrator.myqiniudemo.MainActivity"><TextViewandroid:id="@+id/title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello Qiniu!"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="上傳圖片"android:onClick="clickPost"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="下載圖片"android:onClick="clickDown"/><ImageViewandroid:id="@+id/image"android:layout_width="match_parent"android:layout_height="match_parent"/></LinearLayout>
以上所述是小編給大家介紹的Android中使用七牛雲端儲存進行圖片上傳下載的執行個體代碼,希望對大家有所協助,如果大家有任何疑問請給我留言,小編會及時回複大家的。在此也非常感謝大家對雲棲社區網站的支援!