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

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

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

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

1,选择图片
2

2,上传阿里OSS
在这里插入图片描述

3,发布成功
在这里插入图片描述

一 添加阿里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);
                }
            });
        }
    }

五 尾言

为自己技术增值,量变引起质变.对象亦来源于生活,模式亦来源于验证的OO经验,那么请学会使用轮子,再到感受制造轮子的乐趣,你会发现原来编程那么美妙.如有错误或不当之处,请读者留言,博主好吸取经验,互相交流学习,如果本文对你有帮助请帮博主点赞,发注一波,谢谢善良的读者

  • 10
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
你可以使用阿里云官方提供的 OSS(对象存储服务)SDK 来实现 Android 上的文件上传功能。以下是一个简单的示例代码,需要先引入阿里云 OSS SDK 的依赖: ```java implementation 'com.aliyun.dpa:oss-android-sdk:3.1.8' ``` 然后,在你的代码中使用以下方法来实现文件上传: ```java import com.aliyun.dpa.oss.app.AppServiceFactory; import com.aliyun.dpa.oss.app.OSSClientFactory; import com.aliyun.dpa.oss.app.RunningConfig; import com.aliyun.dpa.oss.app.ServiceFactory; import com.aliyun.dpa.oss.app.UploadConfiguration; import com.aliyun.dpa.oss.app.UploadConfigurationFactory; import com.aliyun.dpa.oss.app.UploadManager; import com.aliyun.dpa.oss.app.util.FileUtil; import com.aliyun.dpa.oss.app.util.StringUtil; import com.aliyun.dpa.oss.app.util.UIUtil; import com.aliyun.dpa.oss.callback.ResultCallback; import com.aliyun.dpa.oss.model.OSSUploadConfiguration; import com.aliyun.dpa.oss.task.PutObjectTask; import com.aliyun.dpa.oss.task.TaskCancelledException; public class AliOSSUploader { private static final String ENDPOINT = "your_oss_endpoint"; // 你的 OSS Endpoint private static final String ACCESS_KEY_ID = "your_access_key_id"; // 你的 Access Key ID private static final String ACCESS_KEY_SECRET = "your_access_key_secret"; // 你的 Access Key Secret private static final String BUCKET_NAME = "your_bucket_name"; // 你的 Bucket 名称 public void uploadFile(String filePath) { // 创建 OSS 客户端 RunningConfig runningConfig = new RunningConfig(ACCESS_KEY_ID, ACCESS_KEY_SECRET, ENDPOINT); AppServiceFactory.init(runningConfig); ServiceFactory serviceFactory = OSSClientFactory.createServiceFactory(); UploadConfiguration configuration = UploadConfigurationFactory.getUploadConfiguration(); UploadManager uploadManager = serviceFactory.createUploadManager(configuration); // 构造上传任务 PutObjectTask putObjectTask = new PutObjectTask(BUCKET_NAME, StringUtil.generateRandomKey(), filePath); // 设置上传结果回调 putObjectTask.setResultCallback(new ResultCallback() { @Override public void onSuccess(Object object) { // 文件上传成功 UIUtil.showToast("文件上传成功"); } @Override public void onFailure(Exception e) { // 文件上传失败 UIUtil.showToast("文件上传失败:" + e.getMessage()); } @Override public void onProgress(Object object, long currentSize, long totalSize) { // 文件上传进度 int progress = (int) (currentSize * 100 / totalSize); UIUtil.showToast("文件上传进度:" + progress + "%"); } @Override public void onCancel(Object object) { // 文件上传取消 UIUtil.showToast("文件上传取消"); } }); // 开始上传任务 try { uploadManager.upload(putObjectTask); } catch (TaskCancelledException e) { // 上传任务取消 UIUtil.showToast("文件上传取消"); } } } ``` 以上代码中的 `your_oss_endpoint`、`your_access_key_id`、`your_access_key_secret` 和 `your_bucket_name` 分别是你的 OSS Endpoint、Access Key ID、Access Key Secret 和 Bucket 名称。你需要将它们替换为你自己的实际值。 调用 `uploadFile` 方法并传入要上传的文件路径,即可实现文件上传阿里云 OSS。记得在 AndroidManifest.xml 中添加网络权限: ```xml <uses-permission android:name="android.permission.INTERNET" /> ``` 希望对你有帮助!如有其他问题,请随时提问。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值