第三方存儲:為了減少開發成本,減輕伺服器壓力,降低分布式開發難度,提高資料安全性,在開發過程中我們常常可以把一些資料存儲到第三方雲服務中。
七牛雲: 中國企業級公有雲服務商,提供對象存儲,融合CDN加速,直播雲等服務。
優勢:對于10GB以下資料免費,提高詳盡的開發者文檔,位址:https://developer.qiniu.com/
實作思路:1.安卓用戶端向伺服器發送請求,表明自己要進行第三方存儲,擷取token
2.伺服器通過伺服器端SDK與第三方互動,表明目的,擷取第三方傳回的token
3.伺服器将token傳回給安卓端,安卓端擷取token
4.安卓用戶端通過用戶端SDK将需要上傳的圖檔和token一起發送到第三方雲
5.用戶端告知伺服器端第三方存儲過程結束
1.用戶端向伺服器端發送請求擷取資料
2.伺服器端通過SDK與第三方互動獲得圖檔的URL,傳回給用戶端
3.安卓用戶端通過URL擷取圖檔
代碼示例:
添加sdk依賴:
public class MainActivity extends AppCompatActivity {
private ProgressDialog progressDlg;
private Intent intent;
private final int NONE=0,LOCAL_PICTURE=1,UPLOAD_TAKE_PICTURE=2,SAVE_THEME_IMAGE=3;
private String takePictureUrl,upToken, imageFileName;
ImageView photo;
TextView select_local_picture;
TextView download_picture;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
photo=(ImageView)findViewById(R.id.imageView); //上傳和下載下傳的圖檔位置
select_local_picture=(TextView)findViewById(R.id.textView); //上傳圖檔的按鈕
download_picture=(TextView)findViewById(R.id.textView2);
//點選選擇本地圖檔
select_local_picture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
"image/*");
startActivityForResult(intent,LOCAL_PICTURE);
}
});
//點選下載下傳圖檔
download_picture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
HashMap map = new HashMap();
map.put("請求類型", "請求下載下傳圖檔");
requestFragment.httpRequest(map, CommonUrl.getPhoto); //伺服器請求
}
});
}
//選擇圖檔完成後
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode==NONE)
return;
//耗時操作傳到handler裡去處理
if(resultCode== Activity.RESULT_OK){
this.intent=data;
handler.sendEmptyMessage(LOCAL_PICTURE);
}
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case LOCAL_PICTURE:
//處理本地選擇的圖檔
Uri uri=intent.getData();
String photo_local_file_path="圖檔位址"; //使用uri擷取圖檔位址略
if (!(photo_local_file_path.toString().toLowerCase().endsWith("jpg")||photo_local_file_path.toString().toLowerCase().endsWith("png")
||photo_local_file_path.toString().toLowerCase().endsWith("jpeg")||photo_local_file_path.toString().toLowerCase().endsWith("gif"))) {
Toast.makeText(MainActivity.this, "不支援此格式的上傳", Toast.LENGTH_LONG).show();
break;
}
//簡單壓縮圖檔
Bitmap bitmap2=PhotoUtil.getInstance().trasformToZoomPhotoAndLessMemory(photo_local_file_path);
Drawable addPicture =new BitmapDrawable(getResources(), bitmap2);
takePictureUrl=photo_local_file_path;
photo.setImageDrawable(addPicture);
{
//imageFileName為存儲在伺服器端的圖檔名
imageFileName = "username" + "/" + takePictureUrl.hashCode() + new Random(System.nanoTime()).toString();
HashMap map = new HashMap();
map.put("請求類型", "請求獲得token");
map.put("image", imageFileName);
Log.d("選擇了本地照片", "正在請求伺服器端擷取token");
requestFragment.httpRequest(map,Url.getToken);
}
break;
case UPLOAD_TAKE_PICTURE: //擷取token之後
{
//使用SDK傳輸到七牛雲
UploadManager uploadmgr = new UploadManager();
File data = new File(takePictureUrl);
String key = imageFileName;
String token = upToken;
progressDlg = ProgressDialog.show(MainActivity.this, "上傳圖檔", "正在上傳圖檔", true, true, new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialogInterface) {
//取消了上傳
}
});
progressDlg.setMax(101);
uploadmgr.put(data, key, token, new UpCompletionHandler() {
@Override
public void complete(String key, ResponseInfo info, JSONObject response) {
//完成,發資訊給業務伺服器
Log.d("to第三方結果",response.toString());
new Thread() {
public void run() {
Map<String, Object> map = new HashMap<>();
Message msg = handler.obtainMessage();
msg.obj = map;
msg.what = SAVE_THEME_IMAGE;
handler.sendMessage(msg);//要上傳的圖檔包裝在msg後變成了消息發到handler
}
}.start();
}
}, new UploadOptions(null, null, false,
new UpProgressHandler() {
public void progress(String key, double percent) {
//mProgress.setProgress((int)percent*100);
progressDlg.setProgress((int) percent * 100);
}
}, null));
}
break;
case SAVE_THEME_IMAGE: //傳到第三方之後告知伺服器
progressDlg.dismiss();
{
HashMap map = new HashMap();
map.put("請求類型","上傳到七牛");
map.put("image",imageFileName);
requestFragment.httpRequest(map, "完成傳輸"); //在伺服器儲存圖檔(隻儲存圖檔名)
}
progressDlg=ProgressDialog.show(MainActivity.this, "上傳圖檔", "正在儲存圖檔", true, true, new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialogInterface) {
//上傳完圖檔後取消了儲存
}
});
break;
default: //使用者身份認證失敗
{
break;
}
}
}
};
//伺服器端的響應
public void requestFinish(String result, String requestUrl) throws JSONException {
Message message = new Message();
//擷取token
if(requestUrl.equals(("擷取密碼"))){
JSONObject jsonObject=new JSONObject(result);
int code = Integer.valueOf(jsonObject.getString("code"));
if (code == 1) {
JSONArray token = jsonObject.getJSONArray("contents");
upToken = token.getString(0);//成功擷取密碼
handler.sendEmptyMessage(UPLOAD_TAKE_PICTURE);
return;
}
else{
Toast.makeText(MainActivity.this, "擷取密碼失敗", Toast.LENGTH_LONG).show();
}
}
if (requestUrl.equals("下載下傳圖檔")) {
JSONObject object = new JSONObject(result);
int code = Integer.valueOf(object.getString("code"));
if (code == 1) {
String url = "從伺服器獲得圖檔的url位址";
//使用picasso等圖檔處理庫擷取圖檔
return;
} else {
// Toast.makeText(profileActivity.this, "未知錯誤", Toast.LENGTH_LONG).show();
return;
}
}
}
}
備注:本文隻讨論用戶端相關操作,不涉及伺服器端的實作
下一節:picasso圖檔處理實踐講解