Android OSS阿里图片上传
2018-05-25 本文已影响56人
Sky_Blue
一 、阿里的官方文档
二、Android图片上传的流程 + OSS
- 选择图片
- 压缩图片
- 构建阿里上传请求对象OSS
- 构建阿里的文件上传对象PutObjectRequest
- PutObjectRequest设置上传进度监听
- OSS对象发起请求asyncPutObject
前面2步我就不写了,主要是写后面这几步。
三、怎么构建阿里的OSS对象
构建OSS对象要一个OSSCredentialProvider,OSSCredentialProvider这个对象有很多子对象,比例可以带Token啥的。
-
创建OSSCredentialProvider对象
/** * 创建OSS对象的OSSCredentialProvider */ public class OSSConfig { // Access Key id 问后台要 public static final String AK = "LTXXXXXXXXQu"; // SecretKeyId 问后台要 public static final String SK = "9eKXXXXXXXXZbkZ"; public static OSSCredentialProvider newCustomSignerCredentialProvider() { return new OSSCustomSignerCredentialProvider() { @Override public String signContent(String content) { return OSSUtils.sign(AK, SK, content); } }; } }
-
创建OSS对象,有网络请求,要异步
/** * 创建OSS对象 */ public OSS getOSS(Context context) { if (mOSS == null) { OSSCredentialProvider provider = OSSConfig.newCustomSignerCredentialProvider(); ClientConfiguration conf = new ClientConfiguration(); conf.setConnectionTimeout(15 * 1000); // 连接超时,默认15秒 conf.setSocketTimeout(15 * 1000); // socket超时,默认15秒 conf.setMaxConcurrentRequest(5); // 最大并发请求书,默认5个 conf.setMaxErrorRetry(2); // 失败后最大重试次数,默认2次 mOSS = new OSSClient(context, endpoint, provider, conf); } return mOSS; }
四、由于上传图片项目经常要用,创建一个管理类来管理图片上传
/**
* OSS图片上传的管理类
*/
public class OssManager {
/**
* 图片上传的地址
* 问后台要的
*/
public static String endpoint = "https://oss-xxxx.com";
/**
* 图片的访问地址的前缀
* 其实就是: bucketName + endpoint
*/
public static String prefix = "https://xxx.oss-xxxx.com/";
/**
* Bucket是OSS上的命名空间
* 问后台要的
*/
public static String bucketName = "xxx";
/**
* 图片保存到OSS服务器的目录,问后台要
*/
public static String dir = "app/";
private OSS mOSS;
private static OssManager mInstance;
public static OssManager getInstance() {
if (mInstance == null) {
synchronized (OssManager.class) {
mInstance = new OssManager();
}
}
return mInstance;
}
/**
* 创建OSS对象
*/
private OSS getOSS(Context context) {
if (mOSS == null) {
OSSCredentialProvider provider = OSSConfig.newCustomSignerCredentialProvider();
ClientConfiguration conf = new ClientConfiguration();
conf.setConnectionTimeout(15 * 1000); // 连接超时,默认15秒
conf.setSocketTimeout(15 * 1000); // socket超时,默认15秒
conf.setMaxConcurrentRequest(5); // 最大并发请求书,默认5个
conf.setMaxErrorRetry(2); // 失败后最大重试次数,默认2次
mOSS = new OSSClient(context, endpoint, provider, conf);
}
return mOSS;
}
/**
* 图片上传
*
* @param context
* @param uploadFilePath 图片的本地路径
* @param onUploadListener 回调监听
*/
public void upload(final Context context, final int position, final String uploadFilePath,
final OnUploadListener onUploadListener) {
Observable.just(context)
.map(new Function<Context, OSS>() {
@Override
public OSS apply(Context context) throws Exception {
return getOSS(context);
}
})
.map(new Function<OSS, String>() {
@Override
public String apply(OSS oss) throws Exception {
// 创建压缩图片的路径
File imageFilePath = FileUtil.createImageFilePath();
// 压缩图片
ImageCompressUtil.compress(context, uploadFilePath, imageFilePath.getAbsolutePath());
// 创建上传的对象
PutObjectRequest put = new PutObjectRequest(bucketName,
dir + getUUIDByRules32Image()
, imageFilePath.getAbsolutePath());
// 上传的进度回调
put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
@Override
public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
if (onUploadListener == null) {
return;
}
onUploadListener.onProgress(position, currentSize, totalSize);
}
});
oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
@Override
public void onSuccess(PutObjectRequest request, PutObjectResult result) {
if (onUploadListener == null) {
return;
}
String imageUrl = request.getObjectKey();
onUploadListener.onSuccess(position, uploadFilePath,
prefix + imageUrl);
}
@Override
public void onFailure(PutObjectRequest request, ClientException clientException, ServiceException serviceException) {
serviceException.printStackTrace();
clientException.printStackTrace();
if (onUploadListener == null) {
return;
}
onUploadListener.onFailure(position);
}
});
return imageFilePath.getAbsolutePath();
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
}
public interface OnUploadListener {
/**
* 上传的进度
*/
void onProgress(int position, long currentSize, long totalSize);
/**
* 成功上传
*/
void onSuccess(int position, String uploadPath, String imageUrl);
/**
* 上传失败
*/
void onFailure(int position);
}
/**
* 上传到后台的图片的名称
*/
public static String getUUIDByRules32Image() {
StringBuffer generateRandStr = null;
try {
String rules = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
int rpoint = 0;
generateRandStr = new StringBuffer();
Random rand = new Random();
int length = 32;
for (int i = 0; i < length; i++) {
if (rules != null) {
rpoint = rules.length();
int randNum = rand.nextInt(rpoint);
generateRandStr.append(rules.substring(randNum, randNum + 1));
}
}
} catch (Exception e) {
e.printStackTrace();
}
if (generateRandStr == null) {
return "getUUIDByRules32Image.png";
}
return generateRandStr + ".png";
}
}
大概的流程就是和开始说的一样。就多了自已定义的监听回调,图片上传可能是多图上传。在回调里加了个回调的位置,以便更新UI或者其它的操作。
五、实际使用
private void uploadImage(final List<ImageBean> images) {
for (int i = 0; i < images.size(); i++) {
ImageBean bean = images.get(i);
OssManager.getInstance().upload(getAppActivity(), i, bean.path,
new OssManager.OnUploadListener() {
@Override
public void onProgress(int position, long currentSize, long totalSize) {
LogUtils.e("position = " + position + " onProgress = " + currentSize);
}
@Override
public void onSuccess(int position, String uploadPath, String imageUrl) {
LogUtils.e("position = " + position + " imageUrl = " + imageUrl
+"\n uploadPath = "+uploadPath);
}
@Override
public void onFailure(int position) {
LogUtils.e("position = " + position);
}
}
);
}
}