前言
很多公司没有太多图片存储需求的时候,很多都是前端把图片通过接口传给后台,但有大量图片需求的时候公司就会购买阿里云进行图片存储,有的是后台去上传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 ------到此结束,欢迎指出不足。