安卓Android阿里OSS上传图片(缩略图使用)三步完成+源码例子

博主在做这块阿里OSS上传,也是踩过不少相关的坑,并且阿里的官方文档也是不是很详细,也翻阅不少文章,感觉有所不足,所以记录本文,希望对后面采坑的读者有所帮助,本文目前只针对安卓端OOS开发,并且后台是做好了相关的工作(使用已经搭建好的应用服务器),那么请往下看

本文核心要点多文件的同步上传or异步上传,单文件上传博主没踩到什么坑,读者应该比博主的聪明

1,选择图片

离线安装阿里oss python sdk 阿里云oss安卓_OSS上次图片

2,上传阿里OSS

离线安装阿里oss python sdk 阿里云oss安卓_安卓上传图片_02

3,发布成功

离线安装阿里oss python sdk 阿里云oss安卓_阿里图片上传_03

一 添加阿里OSS需要依赖(步骤一)

添加完相关依赖,我们进入步骤二,开始

//阿里云OSS上传文件的SDK,上传内层依赖okhttp网络框架
    compile 'com.aliyun.dpa:oss-android-sdk:+'
    compile 'com.squareup.okhttp3:okhttp:3.11.0'
    compile 'com.squareup.okio:okio:1.9.0'

二 触发请求自家服务器索要授权

在触发上传的地方
1,发送自家网络请求,请求自家服务器索要授权
2, 成功返回拿到需要AccessKeyId、AccessKeySecret、SecurityToken、Expiration
3,获取这些信息后,调用阿里SDK,构建OssClient上传即可

P层的请求

/**
     * 上传次数
     */
    int number;
    /**
     * 成功上传(本地文件名作为key,阿里云地址为value)
     */
    List<String> success = new ArrayList<>();
    /**
     * 失败上传(返回失败文件的本地地址)
     */
    List<String> failure = new ArrayList<>();

    public void upOss(final List<String> uris) {
 

        //初始化
        number = 1;
        success.clear();
        failure.clear();

        mGson = new Gson();
        HashMap<String, Object> map = new HashMap<>();
        map.put("type", "release");
        String payload = mGson.toJson(map);

        //封装post请求参数
        Map<String, Object> listMap = new HashMap<>();
        listMap.put("code", 6022);
        listMap.put("token", SPUtil.getString(mContext, Constant.LOGIN_TOKEN, ""));
        listMap.put("payload", payload);

        mDraftM.getVoucherAndUpload(listMap).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new FilterSubscriber<Object>() {

            @Override
            public void onSubscribe(Disposable d) {
            }

            //服务器  给OSS 上传的 秘钥
            @Override
            public void onNext(Object data) {
                String stringData = String.valueOf(data);
                try {
                    JSONObject jsonObject = new JSONObject(stringData);
                    int code = jsonObject.optInt("code");
                    //需要判断code的值做不同的处理
                    if (0 == code) {
                        //请求数据成功,拆分数据
                        Upload6022Bean bean = mGson.fromJson(stringData, Upload6022Bean.class);
                        if (bean != null) {
                            //初始化阿里云OSS   秘钥
                            String accessKeyId = bean.getPayload().getAccessid();
                            String accesskeysecret = bean.getPayload().getAccesskeysecret();  //秘钥
                            String securitytoken = bean.getPayload().getSecuritytoken();

                            String endpoint = bean.getPayload().getHost();          //https://oss-cn-shanghai.aliyuncs.com
                            OSSCredentialProvider credentialProvider = new OSSStsTokenCredentialProvider(accessKeyId, accesskeysecret, securitytoken);
                            OSS oss = new OSSClient(mContext, endpoint, credentialProvider);

                            mObjectKey = bean.getPayload().getDir();                  //hw/test/trends/
                            String bucketName = bean.getPayload().getBucketName();  //kx-common
                            mImagUrl = bean.getPayload().getImg_url();              //https://img.kx.com

                            for (String path : uris) {
                                File file = new File(path);
                                mCrypt = MD5Util.crypt(path);
                                BitmapFactory.Options options = new BitmapFactory.Options();
                                BitmapFactory.decodeFile(file.getAbsolutePath(), options);

                                //获取图片的宽高
                                int height = options.outHeight;
                                int width = options.outWidth;
                                mObjectKeyPath = mObjectKey + width + "_" + height + "_" + mCrypt + ".jpg";

                                // 异步构造上传请求  核心代码 就下面几行  再走阿里,上传给阿里
                                PutObjectRequest objectRequest = new PutObjectRequest(bucketName, mObjectKeyPath, path);

                                oss.asyncPutObject(objectRequest, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
                                    @Override
                                    public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                                        String aliPath = mImagUrl + "/" + request.getObjectKey();  //https://img.kx.com/hw/test/trends/46546.jpg
                                        success.add(aliPath);
                                        if (number == uris.size()) {
                                            //返回 上传路径,以及失败的路径
                                            mJuhuaDialog.dissmiss();
                                            mPublicDyVI.onOssSuccess(success, failure);
                                        }
                                        number++;
                                    }

                                    @Override
                                    public void onFailure(PutObjectRequest request, ClientException clientException, ServiceException serviceException) {
                                        number++;
                                        String aliPath = mImagUrl + "/" + mObjectKey + mCrypt + ".jpg";
                                        failure.add(aliPath);
                                        if (number == uris.size()) {
                                            mJuhuaDialog.dissmiss();
                                            mPublicDyVI.onOssError(success, failure);
                                        }
                                    }
                                });

                                // 异步构造上传请求   end


                                //同步
/*                                PutObjectResult putObjectResult = oss.putObject(objectRequest);
                                String aliPath = mImagUrl + "/" + mObjectKeyPath;//https://img.vistateach.com/hw/test/trends/bf828298f10ada9eafca4c334b971a87.jpg
                                success.add(aliPath);
                                if (number == uris.size()) {
                                    //返回 上传路径,以及失败的路径
                                    mJuhuaDialog.dissmiss();
                                    mPublicDyVI.onOssSuccess(success, failure);
                                }
                                number++;*/
                            }
                            
                        } else {
                            //TODO 获取凭证信息失败
                            mPublicDyVI.onOssError(mErrorMessage);
                        }
                    } else {
                        mPublicDyVI.onOssError(mErrorMessage);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    mPublicDyVI.onOssError(mErrorMessage);
                }
            }

            @Override
            public void onComplete() {
            }

            @Override
            public void onError(String str) {
                mPublicDyVI.onOssError(str);
            }
        });

    }

三 本文核心要点多文件的同步上传or异步上传

1,同步上传:多文件同步上传没有线程或者循环问题,就是用户体验较差,需要等待
2,异步上传: 就有上面叙述问题,上传9张,效果返回多张图一样一样,本地拼接的麻烦

问题:

这里采坑是后台没做callback体封装,不返回拼接的图片下载完整地址,博主自己移动端拼接,产生循环异步问题,我们循环地址列表,循环体里面做阿里OSS上传,就会 跑1,1的回调没回来,在2的回调,回来1和2,上传OSS2张没问题,但我们本地拼接地址出问题,导致两张图一模一样.

解决:

通过回调的onSuccess(PutObjectRequest request, PutObjectResult result ) ,拿request里面的getObjectKey来拼接,result是没有body 因为我们可爱的后台偷懒了.

异步请求核心代码

// 异步构造上传请求  核心代码 就下面几行  再走阿里,上传给阿里
                                PutObjectRequest objectRequest = new PutObjectRequest(bucketName, mObjectKeyPath, path);

                                oss.asyncPutObject(objectRequest, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
                                    @Override
                                    public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                                        String aliPath = mImagUrl + "/" + request.getObjectKey();//https://img.vistateach.com/hw/test/trends/bf828298f10ada9eafca4c334b971a87.jpg

                                        success.add(aliPath);
                                        if (number == uris.size()) {
                                            //返回 上传路径,以及失败的路径
                                            mJuhuaDialog.dissmiss();
                                            mPublicDyVI.onOssSuccess(success, failure);
                                        }
                                        number++;
                                    }

                                    @Override
                                    public void onFailure(PutObjectRequest request, ClientException clientException, ServiceException serviceException) {
                                        number++;
                                        String aliPath = mImagUrl + "/" + mObjectKey + mCrypt + ".jpg";
                                        failure.add(aliPath);
                                        if (number == uris.size()) {
                                            mJuhuaDialog.dissmiss();
                                            mPublicDyVI.onOssError(success, failure);
                                        }
                                    }
                                });

                                // 异步构造上传请求   end

同步上传 核心代码

//同步
/*                                PutObjectResult putObjectResult = oss.putObject(objectRequest);
                                String aliPath = mImagUrl + "/" + mObjectKeyPath;//https://img.vistateach.com/hw/test/trends/bf828298f10ada9eafca4c334b971a87.jpg
                                success.add(aliPath);
                                if (number == uris.size()) {
                                    //返回 上传路径,以及失败的路径
                                    mJuhuaDialog.dissmiss();
                                    mPublicDyVI.onOssSuccess(success, failure);
                                }
                                number++;*/
                            }

四 额外步骤OSS缩略图应用

在原有访问地址拼接尾缀?x-oss-process=image/resize,m_fill,h_高度,w_宽度,提高图片加载速度,访问OSS定义缩略图,提高用户体验

String OSS_SMALL_PIC = "?x-oss-process=image/resize,m_fill,h_200,w_200";

运用核心代码

@Override
    public void onSuccess(DyDetailBean6049.PayloadBean.NewsMapBean newsMap) {
        mTvAddDate1.setText(newsMap.getAdd_date());
        mTvActionText.setText(newsMap.getAction_text());
        mTvDyTitle.setText("课堂标题:  " + newsMap.getTitle());
        mTvDyContent.setText("课堂内容:  " + newsMap.getContent());
        mTv_lesson_time.setText("上课时间:  " + newsMap.getLesson_time());

        final String img_url = newsMap.getImg_url();
        if (!TextUtils.isEmpty(img_url)) {
            //图片地址数组
            final String[] split = img_url.split(",");
            //拼接缩略图尾缀
            for (int i = 0; i < split.length; i++) {
                split[i] = split[i]+ AppConfig.OSS_SMALL_PIC;

            }
            ItemImgAdapter itemImgAdapter = new ItemImgAdapter(this, split);
            mRv.setLayoutManager(new GridLayoutManager(this, 3));
            mRv.setAdapter(itemImgAdapter);

            itemImgAdapter.setOnItemClickListener(new LessonDetaiAdapter.OnItemClickListener() {
                @Override
                public void onItemClick(View view, int position) {
                    // 点击查看大图
                    Intent intent = new Intent(DyDetailActivity.this, VpActivity.class);
                    intent.putExtra("paths", img_url);
                    intent.putExtra("position", position);
                    startActivity(intent);
                }
            });
        }
    }