Android之上传图片到OSS


前言

很多公司没有太多图片存储需求的时候,很多都是前端把图片通过接口传给后台,但有大量图片需求的时候公司就会购买阿里云进行图片存储,有的是后台去上传OSS,为了保险起见也有前端去上传的,可单张和多张上传,今天就谈一下Android上传OSS的一些步骤。


提示:以下是本篇文章正文内容,下面案例可供参考

一、准备好图片路径

关于拍照以及相册选取我上一篇文章有讲,自己去看。

二、使用步骤

1.引入库

代码如下(示例):

 //oss 阿里图片上传
 implementation 'com.aliyun.dpa:oss-android-sdk:+'

2.初始化

我这里是封装好的一个工具类:

private OssUtil ossUtil;//oss上传图片
 //初始化Oss,参数分别是Content,图片统一访问地址 ,存到Oss的目录名称 (如:app/***)
        //accessKeyId,accessKeySecret,endpoint,bucketName(后4个参数是您自己阿里云Oss中参数)
        ossUtil = new OssUtil(this, KeyConfig.osstpdz, "app/user/",
                SpUtil.get(KeyConfig.accessStsToken, ""),
                SpUtil.get(KeyConfig.accessKeyId, ""),
                SpUtil.get(KeyConfig.accessKeySecret, ""),
                KeyConfig.endpoint,
                SpUtil.get(KeyConfig.bucketName, ""));

3.获取OSS相关参数

相关参数由后台反给你,拿到参数进行赋值,这里我封装了一个类。

/**
 * key
 */
public  class KeyConfig {
    
    

    //=============================================阿里oss=============================================
    //初始化OssService类,参数分别是Content,accessKeyId,accessKeySecret,endpoint,bucketName(后4个参数是您自己阿里云Oss中参数)
    public static final String accessKeyId = "*****";
    public static final String accessKeySecret = "****";
    public static final String accessStsToken = "****";
    public static final String bucketName = "****";
    public static final String endpoint = "****";
    //----------TODO 以上数据为了安全直接从后台取 但是也可以直接使用--------------
    public static final String osstpdz = "****";//图片统一访问地址  静态地址路径

}

4.上传

  /**
     * OSS上传图片
     *
     * @param imgurl
     */
    private void OSSImag(String imgurl) {
    
    
        ossUtil.uploadImage(imgurl, new OSSCallback() {
    
    
            @Override
            public void onSuccess(final List<String> allPath) {
    
    
                runOnUiThread(new Runnable() {
    
    
                    @Override
                    public void run() {
    
    
                        //上传成功
                        rightDatelistqsc("2", allPath.get(0) + "");
                    }
                });
            }

            @Override
            public void onFailure(ClientException clientException, ServiceException serviceException) {
    
    
                //上传失败
                runOnUiThread(new Runnable() {
    
    
                    @Override
                    public void run() {
    
    
                        ToastUtils.ToastCllShow("上传失败");
                    }
                });
            }
        });
    }

三、OssUtil工具类

package com.wzj.footprint.utils;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.sdk.android.oss.ClientConfiguration;
import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.OSS;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.callback.OSSProgressCallback;
import com.alibaba.sdk.android.oss.common.OSSLog;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSStsTokenCredentialProvider;
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
import com.alibaba.sdk.android.oss.model.CompleteMultipartUploadResult;
import com.alibaba.sdk.android.oss.model.MultipartUploadRequest;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.wzj.footprint.model.OssAddBean;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;

/**
 * oss
 */
public class OssUtil {
    
    

    private static final String TAG = "=====OssUtil===>>>";
    private Context context;
    private String uploadFilePath ;//上传文件目录名称
    private String filehttpUrl;//图片,视频 统一访问地址
    private String accessKeyId;
    private String bucketName;
    private String accessKeySecret;
    private String accessToken;
    private String endpoint;
    private int number;
    public OSSUploadHelperCallback callback;
    private OSS client;
    List<String> successPath = new ArrayList<>();
    Map<String, String> successPathMap = new IdentityHashMap<String, String>();

    public OssUtil(Context context, String filehttpUrl, String uploadFilePath, String accessToken, String accessKeyId, String accessKeySecret, String endpoint, String bucketName) {
    
    
        this.context = context;
        this.filehttpUrl = filehttpUrl;
        this.uploadFilePath = uploadFilePath;
        this.endpoint = endpoint;
        this.bucketName = bucketName;
        this.accessKeyId = accessKeyId;
        this.accessKeySecret = accessKeySecret;
        this.accessToken = accessToken;
    }

    public void OSSStas() {
    
    
        getNetOssStsToken();
    }

    //OSS的配置,建议只实例化一次,即不要放在循环体中。
    public OSS getOSSClient() {
    
    
        if (false) {
    
    
            OSSLog.enableLog();
        }
        //这个初始化安全性没有Sts安全
//        OSSCredentialProvider credentialProvider = new OSSPlainTextAKSKCredentialProvider(accessKeyId, accessKeySecret);

        // 推荐使用
        OSSCredentialProvider credentialProvider = new OSSStsTokenCredentialProvider(accessKeyId, accessKeySecret, accessToken);

        ClientConfiguration conf = new ClientConfiguration();
        conf.setConnectionTimeout(15 * 1000); // 连接超时,默认15秒
        conf.setSocketTimeout(15 * 1000); // socket超时,默认15秒
        conf.setMaxConcurrentRequest(5); // 最大并发请求数,默认5个
        conf.setMaxErrorRetry(2); // 失败后最大重试次数,默认2次

        // oss为全局变量,endpoint是一个OSS区域地址
        return new OSSClient(context, endpoint, credentialProvider, conf);
    }

    /**
     * 多图片上传方法
     *
     * @param paths 需上传文件的路径
     */
    private void uploads(final List<String> paths) {
    
    
        if (client == null) {
    
    
            return;
        }
        successPath.clear();
        successPathMap.clear();
        number = 1;
        for (String path : paths) {
    
    
            // 构造上传请求
            PutObjectRequest request = new PutObjectRequest(bucketName, getObjectKey(path), path);
            // 异步上传可回调上传进度。
            request.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
    
    
                @Override
                public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
    
    
//                    Log.d(TAG, "PutObject"+"currentSize: " + currentSize + " totalSize: " + totalSize);
//                    int progress = (int) (100 * currentSize / totalSize);
//                    Log.d(TAG,"上传进度="+progress);
                    //上传成功
//                    successPath.add(getAllPath(request.getObjectKey()));
//                    successPathMap.put(request.getUploadFilePath(),getAllPath(request.getObjectKey()));
//                    if (number == paths.size() && callback != null) {
    
    
//                        callback.onSuccess(successPath);
//                    }
//                    if (number == paths.size() && callbackmap != null) {
    
    
//                        callbackmap.onSuccess(successPathMap);
//                    }
//                    number++;
                }
            });

            //同步上传回调
            OSSAsyncTask ptask = client.asyncPutObject(request, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
    
    
                @Override
                public void onSuccess(PutObjectRequest request, PutObjectResult result) {
    
    
                    Log.e(TAG, request.getUploadFilePath() + "===上传成功11== :" + getAllPath(request.getObjectKey()));
                    //上传成功
                    successPath.add(getAllPath(request.getObjectKey()));
                    successPathMap.put(new String(request.getUploadFilePath()), getAllPath(request.getObjectKey()));
                    if (number == paths.size() && callback != null) {
    
    
                        callback.onSuccess(successPath);
                        callback.onSuccess(successPathMap);
                    }
                    number++;
                }

                @Override
                public void onFailure(PutObjectRequest request, ClientException clientException, ServiceException serviceException) {
    
    
                    //上传失败
                    if (callback != null) {
    
    
                        callback.onFailure(clientException, serviceException);
                    }

                    if (clientException != null) {
    
    
                        // 本地异常如网络异常等
                        Log.e(TAG, "UploadFailure:表示向OSS发送请求或解析来自OSS的响应时发生错误。\n" +
                                "  *例如,当网络不可用时,这个异常将被抛出");
                        Log.e(TAG, "ErrorCode :" + clientException.getMessage());
                        Log.e(TAG, "==========================================");
                        clientException.printStackTrace();
                    }

                    if (serviceException != null) {
    
    
                        // 服务异常
                        Log.e(TAG, "===UploadFailure:表示在OSS服务端发生错误====");
                        Log.e(TAG, "ErrorCode :" + serviceException.getErrorCode());
                        Log.e(TAG, "RequestId :" + serviceException.getRequestId());
                        Log.e(TAG, "HostId :" + serviceException.getHostId());
                        Log.e(TAG, "RawMessage :" + serviceException.getRawMessage());
                        Log.e(TAG, "==========================================");
//                        if(serviceException.getErrorCode().equals("InvalidAccessKeyId")){
    
    
//                            //token过期
//                            getNetOssStsToken();
//                        }
                    }

                }

            });
            //ptask.cancel(); // 可以取消任务
            //ptask.waitUntilFinished(); // 可以等待直到任务完成

        }
    }

    /**
     * 分片上传
     */
    private long ztotalSize;//多个文件总size
    private long scZtotalSize;//多个文件上传的总size

    public void uploadMultipart(final List<String> paths, final OSSUploadHelperCallback callback) {
    
    
        this.callback = callback;
        if (client == null) {
    
    
            return;
        }
        ztotalSize = 0;
        scZtotalSize = 0;
        successPath.clear();
        successPathMap.clear();
        number = 1;
        for (String path : paths) {
    
    
            MultipartUploadRequest request = new MultipartUploadRequest(bucketName, getObjectKey(path), path);
            // 回调上传进度。
            File file = new File(path);
            ztotalSize += file.length();
            request.setProgressCallback(new OSSProgressCallback<MultipartUploadRequest>() {
    
    
                @Override
                public void onProgress(MultipartUploadRequest request, long currentSize, long totalSize) {
    
    
                    Log.e(TAG, request.getUploadFilePath() + "===上传成功== :" + request.getObjectKey());
//                    Log.d("PutObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
                    if (currentSize == totalSize) {
    
    //表示第N个文件传完
                        if (!paths.get(paths.size() - 1).equals(request.getUploadFilePath())) {
    
    //还要判断是否是最后一个文件
                            scZtotalSize += totalSize;
                            currentSize = 0;
                        }
                    }
                    int progress = (int) (100 * (currentSize + scZtotalSize) / ztotalSize);
                    Log.d(TAG, "上传进度=" + progress);
                    callback.onProgres(progress);
                }
            });

            //同步上传回调
            OSSAsyncTask task = client.asyncMultipartUpload(request, new OSSCompletedCallback<MultipartUploadRequest, CompleteMultipartUploadResult>() {
    
    
                @Override
                public void onSuccess(MultipartUploadRequest request, CompleteMultipartUploadResult result) {
    
    
//                    Log.e(TAG, request.getUploadFilePath()+"===上传成功== :" + request.getObjectKey());
                    //上传成功
                    successPath.add(getAllPath(request.getObjectKey()));
                    successPathMap.put(new String(request.getUploadFilePath()), getAllPath(request.getObjectKey()));
                    if (number == paths.size() && callback != null) {
    
    
                        callback.onSuccess(successPath);
                        callback.onSuccess(successPathMap);
                    }
                    number++;
                }

                @Override
                public void onFailure(MultipartUploadRequest request, ClientException clientException, ServiceException serviceException) {
    
    
                    OSSLog.logError(serviceException.getRawMessage());
                    //上传失败
                    if (callback != null) {
    
    
                        callback.onFailure(clientException, serviceException);
                    }


                    if (clientException != null) {
    
    
                        // 本地异常如网络异常等
                        Log.e(TAG, "UploadFailure:表示向OSS发送请求或解析来自OSS的响应时发生错误。\n" +
                                "  *例如,当网络不可用时,这个异常将被抛出");
                        Log.e(TAG, "ErrorCode :" + clientException.getMessage());
                        Log.e(TAG, "==========================================");
                        clientException.printStackTrace();
                    }

                    if (serviceException != null) {
    
    
                        // 服务异常
                        Log.e(TAG, "===UploadFailure:表示在OSS服务端发生错误====");
                        Log.e(TAG, "ErrorCode :" + serviceException.getErrorCode());
                        Log.e(TAG, "RequestId :" + serviceException.getRequestId());
                        Log.e(TAG, "HostId :" + serviceException.getHostId());
                        Log.e(TAG, "RawMessage :" + serviceException.getRawMessage());
                        Log.e(TAG, "==========================================");
//                        if(serviceException.getErrorCode().equals("InvalidAccessKeyId")){
    
    
//                            //token过期
//                            getNetOssStsToken();
//                        }
                    }
                }
            });
            //task.cancel();//取消分片上传。
            //task.waitUntilFinished();// 可以等待直到任务完成


        }
    }


    /**
     * 分片上传
     */
    public List<OssAddBean> successBean = new ArrayList<>();

    public void uploadMultipartBean(final List<OssAddBean> ossAddBeans, final OSSUploadHelperCallback callback) {
    
    
        this.callback = callback;
        if (client == null) {
    
    
            return;
        }
        ztotalSize = 0;
        scZtotalSize = 0;
        successPath.clear();
        successPathMap.clear();
        number = 1;
        for (final OssAddBean ossbean : ossAddBeans) {
    
    
            MultipartUploadRequest request = new MultipartUploadRequest(bucketName, getObjectKey(ossbean.getPaths()), ossbean.getPaths());
            // 回调上传进度。
            File file = new File(ossbean.getPaths());
            ztotalSize += file.length();
            request.setProgressCallback(new OSSProgressCallback<MultipartUploadRequest>() {
    
    
                @Override
                public void onProgress(MultipartUploadRequest request, long currentSize, long totalSize) {
    
    
//                    Log.e(TAG, request.getUploadFilePath()+"===上传成功== :" + request.getObjectKey());
//                    Log.d("PutObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
                    if (currentSize == totalSize) {
    
    //表示第N个文件传完
                        if (!ossAddBeans.get(ossAddBeans.size() - 1).equals(request.getUploadFilePath())) {
    
    //还要判断是否是最后一个文件
                            scZtotalSize += totalSize;
                            currentSize = 0;
                        }
                    }
                    int progress = (int) (100 * (currentSize + scZtotalSize) / ztotalSize);
                    Log.d(TAG, "上传进度=" + progress);
                    callback.onProgres(progress);
                }
            });

            //同步上传回调
            OSSAsyncTask task = client.asyncMultipartUpload(request, new OSSCompletedCallback<MultipartUploadRequest, CompleteMultipartUploadResult>() {
    
    
                @Override
                public void onSuccess(MultipartUploadRequest request, CompleteMultipartUploadResult result) {
    
    
//                    Log.e(TAG, ossbean.getType()+"===上传成功== :" + request.getObjectKey());
                    //上传成功
                    successBean.add(new OssAddBean(ossbean.getIndex(), getAllPath(request.getObjectKey()), ossbean.getIde(), ossbean.getType()));
                    if (number == ossAddBeans.size() && successBean != null) {
    
    
                        callback.onSuccessben(successBean);
                    }
                    number++;
                }

                @Override
                public void onFailure(MultipartUploadRequest request, ClientException clientException, ServiceException serviceException) {
    
    
                    OSSLog.logError(serviceException.getRawMessage());
                    //上传失败
                    if (callback != null) {
    
    
                        callback.onFailure(clientException, serviceException);
                    }


                    if (clientException != null) {
    
    
                        // 本地异常如网络异常等
                        Log.e(TAG, "UploadFailure:表示向OSS发送请求或解析来自OSS的响应时发生错误。\n" +
                                "  *例如,当网络不可用时,这个异常将被抛出");
                        Log.e(TAG, "ErrorCode :" + clientException.getMessage());
                        Log.e(TAG, "==========================================");
                        clientException.printStackTrace();
                    }

                    if (serviceException != null) {
    
    
                        // 服务异常
                        Log.e(TAG, "===UploadFailure:表示在OSS服务端发生错误====");
                        Log.e(TAG, "ErrorCode :" + serviceException.getErrorCode());
                        Log.e(TAG, "RequestId :" + serviceException.getRequestId());
                        Log.e(TAG, "HostId :" + serviceException.getHostId());
                        Log.e(TAG, "RawMessage :" + serviceException.getRawMessage());
                        Log.e(TAG, "==========================================");
//                        if(serviceException.getErrorCode().equals("InvalidAccessKeyId")){
    
    
//                            //token过期
//                            getNetOssStsToken();
//                        }
                    }
                }
            });
            //task.cancel();//取消分片上传。
            //task.waitUntilFinished();// 可以等待直到任务完成


        }
    }


    // 拼接自己服务器的URL
    private String getAllPath(String objectKey) {
    
    
        String imageUrl = "";
        if (!TextUtils.isEmpty(objectKey)) {
    
    
//            int i = objectKey.lastIndexOf("/");
//            String substring = objectKey.substring(i + 1, objectKey.length());
//            imageUrl = imghttpUrl + uploadFilePath + substring;
//            Log.e("Oss==>>", substring);
//            Log.e("Oss==>>", imageUrl);

            imageUrl = filehttpUrl + objectKey;

        }
        return imageUrl;
    }


    /**
     * 上传单个文件   (图片,视频,gif,.....)
     *
     * @param path     本地地址
     * @param callback 成功回调
     */
    public void uploadImage(String path, OSSUploadHelperCallback callback) {
    
    
        this.callback = callback;
        List<String> strings = new ArrayList<>();
        strings.add(path);
        uploads(strings);
    }


    /**
     * 上传多文件   (图片,视频,gif,.....)
     *
     * @param paths    本地地址
     * @param callback 成功回调
     */
    public void uploadImages(List<String> paths, OSSUploadHelperCallback callback) {
    
    
        this.callback = callback;
        uploads(paths);
    }


    /**
     * 获取OssToken    并上传文件
     *
     * @param path     本地地址
     * @param callback 成功回调
     */
//    public void uploadImageT(Context context, String path, OSSUploadHelperCallback callback) {
    
    
//        this.callback = callback;
//        OkGo.<BaseRespose<OSSTokenBean>>post(Api.formatUrl("/XinBu/OssValues?user=lianyou-oss&token=5c413c4158db33132824a16e"))
//                .tag(context)
//                .execute(new DialogCallback<BaseRespose<OSSTokenBean>>(context, false) {
    
    
//                    @Override
//                    public void onSuccess(Response<BaseRespose<OSSTokenBean>> response) {
    
    
//                        OSSTokenBean ossTokenBean = response.body().data;
//                        ENDPOINT = ossTokenBean.getPoint();
//                        BUCKET_NAME = ossTokenBean.getDucketName();
//                        OSS_ACCESS_KEY_ID = ossTokenBean.getAccessKeyId();
//                        OSS_ACCESS_KEY_SECRET = ossTokenBean.getAccessKeySecret();
//                        uploadFilePath = ossTokenBean.getUploadFilePath();
//                        //得到client
//                        client = getOSSClient();
//                        List<String> strings = new ArrayList<>();
//                        strings.add(path);
//                        uploads(strings);
//                    }
//                });
//    }


    /**
     * 取得系统时间
     *
     * @return 时间戳
     */
    private String getDateString() {
    
    
        return System.currentTimeMillis() + "";
    }

    /**
     * 返回key
     *
     * @param path 本地路径
     * @return key
     */
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");// 格式化时间
    private Date date = new Date();// 获取当前时间

    //格式: app/uploadFilePath/2021/04/21/sfdsgfsdvsdfdsfs.jpg
    private String getObjectKey(String path) {
    
    
        Log.e("Oss==>>", path);
        Log.e("Oss==>>", String.format(uploadFilePath + sdf.format(date) + "/" + "%s." + getFormatName(path), getDateString()));
        return String.format(uploadFilePath + sdf.format(date) + "/" + "%s." + getFormatName(path), getDateString());
    }

    /**
     * 获取文件格式名
     */
    private String getFormatName(String fileName) {
    
    
        //去掉首尾的空格
        fileName = fileName.trim();
        String s[] = fileName.split("\\.");
        if (s.length >= 2) {
    
    
            return s[s.length - 1];
        }
        return "";
    }

    public interface OSSUploadHelperCallback {
    
    
        //list上传成功
        void onSuccess(List<String> allPath);

        //map上传成功
        void onSuccess(Map<String, String> allPathMap);

        //bean上传成功
        void onSuccessben(List<OssAddBean> allossbean);

        //上传失败
        void onFailure(ClientException clientException, ServiceException serviceException);

        //上传进度
        void onProgres(int progress);
    }

    /**
     * 获取Oss 的ststoken
     */
    public void getNetOssStsToken() {
    
    
        bucketName = SpUtil.get(KeyConfig.bucketName, "");
        accessKeyId = SpUtil.get(KeyConfig.accessKeyId, "");
        accessKeySecret = SpUtil.get(KeyConfig.accessKeySecret, "");
        accessToken = SpUtil.get(KeyConfig.accessStsToken, "");
        endpoint = SpUtil.get(KeyConfig.endpoint, "");
        filehttpUrl = SpUtil.get(KeyConfig.osstpdz, "");
        //得到client
        client = getOSSClient();

    }

}

四、OssAddBean

package com.wzj.footprint.model;

public class OssAddBean {
    
    
    private int index;
    private String paths; //文件路径
    private String ide;   //标识
    private String type; //类型 TP SP YY

    public OssAddBean(int index,String paths, String ide, String type) {
    
    
        this.index = index;
        this.paths = paths;
        this.ide = ide;
        this.type = type;
    }

    public OssAddBean(String paths, String ide, String type) {
    
    
        this.paths = paths;
        this.ide = ide;
        this.type = type;
    }

    public OssAddBean(String paths, String type) {
    
    
        this.paths = paths;
        this.type = type;
    }

    public int getIndex() {
    
    
        return index;
    }

    public void setIndex(int index) {
    
    
        this.index = index;
    }

    public OssAddBean(String paths) {
    
    
        this.paths = paths;
    }

    public String getIde() {
    
    
        return ide;
    }

    public void setIde(String ide) {
    
    
        this.ide = ide;
    }

    public String getType() {
    
    
        return type;
    }

    public void setType(String type) {
    
    
        this.type = type;
    }

    public String getPaths() {
    
    
        return paths;
    }

    public void setPaths(String paths) {
    
    
        this.paths = paths;
    }
}

五、OSSCallback

package com.wzj.footprint.utils;

import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.ServiceException;
import com.wzj.footprint.model.OssAddBean;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

//oss上传回调
public  class OSSCallback implements OssUtil.OSSUploadHelperCallback {
    
    

    //上传成功List
    @Override
    public void onSuccess(List<String> allPath) {
    
    

    }
    //上传成功Map
    @Override
    public void onSuccess(Map<String, String> allPathMap) {
    
    

    }

    @Override
    public void onSuccessben(List<OssAddBean> allossbean) {
    
    

    }

    //上传失败
    @Override
    public void onFailure(ClientException clientException, ServiceException serviceException) {
    
    

    }
    //上传进度
    @Override
    public void onProgres(int progress) {
    
    

    }
}

总结

总结一下上传步骤:

1:导入库 2:初始化工具类 3:准备好图片路径调起上传 4:封装工具类和Javabean ------到此结束,欢迎指出不足。

猜你喜欢

转载自blog.csdn.net/Android_Cll/article/details/125672996