天天看点

安卓+七牛云的第三方图片存储实践

第三方存储:为了减少开发成本,减轻服务器压力,降低分布式开发难度,提高数据安全性,在开发过程中我们常常可以把一些数据存储到第三方云服务中。

七牛云: 中国企业级公有云服务商,提供对象存储,融合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图片处理实践讲解