客户端阿里云oss图片上传有两种形式。

  1. 一种是通过搭建私有服务,客户端通过获取实时授权口令之后上传图片。
  2. 另一种是通过直传的方式,无需口令,直接将图片上传到阿里云服务器。

两种各有优点,第一种适合安全性私密性要求比较高的项目,第二种则适合安全性要求低,实时性要求高的项目。

两种上传方式又包含同步上传和异步上传两种传输形式。

下面以【直传】方式的【同步上传】为例介绍阿里云oss图片上传流程。

包含

  • 普通同步上传
  • 断点续传同步上传

一、准备工作

准备你的Config文件

import android.os.Environment;

import java.io.File;

public class Config {

    // To run the sample correctly, the following variables must have valid values.
    // The endpoint value below is just the example. Please use proper value according to your region

    // 访问的endpoint地址,与你的存储区域有关系
    public static final String OSS_ENDPOINT = "http://oss-cn-shanghai.aliyuncs.com";
    //callback 测试地址
    public static final String OSS_CALLBACK_URL = "http://oss-demo.aliyuncs.com:23450";
    // STS 鉴权服务器地址,使用前请参照文档 https://help.aliyun.com/document_detail/31920.html 介绍配置STS 鉴权服务器地址。
    // 或者根据工程sts_local_server目录中本地鉴权服务脚本代码启动本地STS 鉴权服务器。详情参见sts_local_server 中的脚本内容。
    public static final String STS_SERVER_URL = "http://*.*.*.*:*/sts/getsts";//STS 地址,私有服务地址,非必选
 
    public static final String BUCKET_NAME = "bucket-spar";// 上传的仓库名
    public static final String OSS_ACCESS_KEY_ID = "你的OSS_ACCESS_KEY_ID";
    public static final String OSS_ACCESS_KEY_SECRET = "你的OSS_ACCESS_KEY_SECRET";


    //下面是非必选
    public static final int DOWNLOAD_SUC = 1;
    public static final int DOWNLOAD_Fail = 2;
    public static final int UPLOAD_SUC = 3;
    public static final int UPLOAD_Fail = 4;
    public static final int UPLOAD_PROGRESS = 5;
    public static final int LIST_SUC = 6;
    public static final int HEAD_SUC = 7;
    public static final int RESUMABLE_SUC = 8;
    public static final int SIGN_SUC = 9;
    public static final int BUCKET_SUC = 10;
    public static final int GET_STS_SUC = 11;
    public static final int MULTIPART_SUC = 12;
    public static final int STS_TOKEN_SUC = 13;
    public static final int FAIL = 9999;
    public static final int REQUESTCODE_AUTH = 10111;
    public static final int REQUESTCODE_LOCALPHOTOS = 10112;
    public static final int REQUESTCODE_OPEN_DOCUMENT = 10113;
}

二、普通同步上传

示例:


    /**
     * 上传方法,普通同步上传(备份。原来用的这个,后续用的断点续传)
     *
     * @param objectKey 标识
     * @param path      需上传文件的路径
     * @return 外网访问的路径
     */
    private static String uploadNormal(String objectKey, String path) {
        try {
            // 构造上传请求
            PutObjectRequest request =
                    new PutObjectRequest(BUCKET_NAME,
                            objectKey, path);
            //得到client
            OSS client = getOSSClient();
            //上传获取结果
            PutObjectResult result = client.putObject(request);
            //获取可访问的url
            String url = client.presignPublicObjectURL(BUCKET_NAME, objectKey);
            //格式打印输出
            Log.e(String.format("PublicObjectURL:%s", url));
            return url;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

三、断点续传同步上传

官方文档:断点续传官方文档

示例:

    /**
     * 上传方法,断点续传同步上传
     *
     * @param objectKey 标识
     * @param path      需上传文件的路径
     * @return 外网访问的路径
     */
    private static String upload(String objectKey, String path) {
        try {
            String recordDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/oss_record/";
            File recordDir = new File(recordDirectory);
            // 确保断点记录的保存文件夹已存在,如果不存在则新建断点记录的保存文件夹。
            if (!recordDir.exists()) {
                recordDir.mkdirs();
            }
            // 创建断点续传上传请求,并指定断点记录文件的保存路径,保存路径为断点记录文件的绝对路径。
            ResumableUploadRequest request = new ResumableUploadRequest(BUCKET_NAME, objectKey, path, recordDirectory);
            // 调用OSSAsyncTask cancel()方法时,设置DeleteUploadOnCancelling为false,表示不删除断点记录文件,下次再上传同一个文件时将从断点记录处继续上传。如果不设置此参数,则默认值为true,表示删除断点记录文件,下次再上传同一个文件时则重新上传。
            request.setDeleteUploadOnCancelling(false);
            // 设置上传回调。
            request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
                @Override
                public void onProgress(ResumableUploadRequest request, long currentSize, long totalSize) {
                    Log.d("resumableUpload currentSize: " + currentSize + " totalSize: " + totalSize);
                }
            });
            //得到client
            OSS client = getOSSClient();
            //上传获取结果
            ResumableUploadResult result = client.resumableUpload(request);
            String url = "";
            if (result != null) {
                url = result.getLocation();//图片在服务器的地址
            }
            //格式打印输出
            Log.e(String.format("PublicObjectURL:%s", url));
            return url;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

四、图片上传工具类完整版


import android.os.Environment;
import android.text.format.DateFormat;

import com.alibaba.sdk.android.oss.OSS;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.callback.OSSProgressCallback;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSPlainTextAKSKCredentialProvider;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.alibaba.sdk.android.oss.model.ResumableUploadRequest;
import com.alibaba.sdk.android.oss.model.ResumableUploadResult;
import com.storecs.westore.base.Log;
import com.storecs.westore.base.app.MyApp;

import java.io.File;
import java.util.Date;


public class UploadHelper {

    //与个人的存储区域有关
    private static final String ENDPOINT = Config.OSS_ENDPOINT;
    //上传仓库名
    private static final String BUCKET_NAME = Config.BUCKET_NAME;
    private static final String ACCESS_KEY_ID = Config.OSS_ACCESS_KEY_ID;
    private static final String ACCESS_KEY_SECRET = Config.OSS_ACCESS_KEY_SECRET;

    private static OSS getOSSClient() {
        OSSCredentialProvider credentialProvider =
                new OSSPlainTextAKSKCredentialProvider(ACCESS_KEY_ID,
                        ACCESS_KEY_SECRET);
        return new OSSClient(MyApp.getContext(), ENDPOINT, credentialProvider);
    }

    /**
     * 上传方法,断点续传同步上传
     *
     * @param objectKey 标识
     * @param path      需上传文件的路径
     * @return 外网访问的路径
     */
    private static String upload(String objectKey, String path) {
        try {
            String recordDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/oss_record/";
            File recordDir = new File(recordDirectory);
            // 确保断点记录的保存文件夹已存在,如果不存在则新建断点记录的保存文件夹。
            if (!recordDir.exists()) {
                recordDir.mkdirs();
            }
            // 创建断点续传上传请求,并指定断点记录文件的保存路径,保存路径为断点记录文件的绝对路径。
            ResumableUploadRequest request = new ResumableUploadRequest(BUCKET_NAME, objectKey, path, recordDirectory);
            // 调用OSSAsyncTask cancel()方法时,设置DeleteUploadOnCancelling为false,表示不删除断点记录文件,下次再上传同一个文件时将从断点记录处继续上传。如果不设置此参数,则默认值为true,表示删除断点记录文件,下次再上传同一个文件时则重新上传。
            request.setDeleteUploadOnCancelling(false);
            // 设置上传回调。
            request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
                @Override
                public void onProgress(ResumableUploadRequest request, long currentSize, long totalSize) {
                    Log.d("resumableUpload currentSize: " + currentSize + " totalSize: " + totalSize);
                }
            });
            //得到client
            OSS client = getOSSClient();
            //上传获取结果
            ResumableUploadResult result = client.resumableUpload(request);
            String url = "";
            if (result != null) {
                url = result.getLocation();//图片在服务器的地址
            }
            //格式打印输出
            Log.e(String.format("PublicObjectURL:%s", url));
            return url;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 上传方法,普通同步上传(备份。原来用的这个,后续用的断点续传)
     *
     * @param objectKey 标识
     * @param path      需上传文件的路径
     * @return 外网访问的路径
     */
    private static String uploadNormal(String objectKey, String path) {
        try {
            // 构造上传请求
            PutObjectRequest request =
                    new PutObjectRequest(BUCKET_NAME,
                            objectKey, path);
            //得到client
            OSS client = getOSSClient();
            //上传获取结果
            PutObjectResult result = client.putObject(request);
            //获取可访问的url
            String url = client.presignPublicObjectURL(BUCKET_NAME, objectKey);
            //格式打印输出
            Log.e(String.format("PublicObjectURL:%s", url));
            return url;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

    /**
     * 上传普通图片
     *
     * @param name 图片名称
     * @param path 本地地址
     * @return 服务器地址
     */
    public static String uploadImage(String name, String path) {
        String key = getObjectImageKey(name);
        return upload(key, path);
    }

    /**
     * 上传头像
     *
     * @param name 图片名称
     * @param path 本地地址
     * @return 服务器地址
     */
    public static String uploadPortrait(String name, String path) {
        String key = getObjectPortraitKey(name);
        return upload(key, path);
    }

    /**
     * 上传audio
     *
     * @param path 本地地址
     * @return 服务器地址
     */
    public static String uploadAudio(String path) {
        String key = getObjectAudioKey(path);
        return upload(key, path);
    }


    /**
     * 获取时间
     *
     * @return 时间戳 例如:201805
     */
    private static String getDateString() {
        return DateFormat.format("yyyyMM", new Date()).toString();
    }

    /**
     * 上传照片
     * 返回key
     * <p>
     * //     * @param path 本地路径
     *
     * @param objectKey 文件名
     * @return key
     */
    //格式: photo/sfdsgfsdvsdfdsfs.jpg,上传到远程到photo目录里
    private static String getObjectImageKey(String objectKey) {
        return String.format("photo/%s", objectKey);
    }

    /**
     * 上传头像
     * //     * @param path
     *
     * @param objectKey 文件名
     * @return
     */
    //格式: image/sfdsgfsdvsdfdsfs.jpg
    private static String getObjectPortraitKey(String objectKey) {
        return String.format("image/%s", objectKey);
    }

    //格式: audio/201805/sfdsgfsdvsdfdsfs.mp3
    private static String getObjectAudioKey(String path) {
        String fileMd5 = HashUtil.getMD5String(new File(path));
        String dateString = getDateString();
        return String.format("audio/%s/%s.mp3", dateString, fileMd5);
    }

}

参考:Android使用阿里云OSS存储文件上传