Android图片上传
背景:图片上传是一般项目都会涉及到的功能,本篇抽取项目中图片上传的流程,做个记录,不至于以后无处查阅。
1、MainActivity1界面样式:点击添加按钮跳转到图片选择的界面,这个业务逻辑很简单就不贴代码了。不过下面的空白部分是一个recycleView,用来显示图片的
2、点击添加图片的按钮
在这里用到了
https://github.com/yanzhenjie/Album这位老哥封装好的读取手机图片的框架
可以选择本地的图片或者视频,或者拍照录制的文件,一行代码搞定复杂的图片获取
有兴趣的可以参考他的使用文档
Album.image(OnlineBookingUI3.this) // 选择图片。
.multipleChoice()
.requestCode(200 )
.camera(false)//不允许拍照
.columnCount(3)//列数
.widget(getWight())//设置标题栏
.selectCount(20-//默认选择的数量mAdapter.getDatas().size() +1)
.listener(new AlbumListener<ArrayList<AlbumFile>>() {//监听选择的结果,异步的
@Override
public void onAlbumResult(int requestCode, @NonNull ArrayList<AlbumFile> result) {
showHideText();
}
@Override
public void onAlbumCancel(int requestCode) {
}
})
.start();
看看这个widget(getWight())//设置标题栏的方法,选择完成后,我们返回,或者说确定自己的选择都会调用这个标题栏的方法
/**
* 更改图片选择器的title
* @return
*/
public Widget getWight() {
return Widget.newDarkBuilder(context)
.statusBarColor(ContextCompat.getColor(context, com.yanzhenjie.album.R.color.album_ColorPrimaryDark))
.toolBarColor(ContextCompat.getColor(context, com.yanzhenjie.album.R.color.album_ColorPrimary))
.navigationBarColor(ContextCompat.getColor(context, com.yanzhenjie.album.R.color.album_ColorPrimaryBlack))
.title("照片列表")
.mediaItemCheckSelector(ContextCompat.getColor(context, com.yanzhenjie.album.R.color.album_WhiteGray),
ContextCompat.getColor(context, com.yanzhenjie.album.R.color.album_ColorPrimary))
.bucketItemCheckSelector(ContextCompat.getColor(context, com.yanzhenjie.album.R.color.album_WhiteGray),
ContextCompat.getColor(context, com.yanzhenjie.album.R.color.album_ColorPrimary))
.buttonStyle(
Widget.ButtonStyle.newDarkBuilder(context)
.setButtonSelector(ContextCompat.getColor(context, com.yanzhenjie.album.R.color.album_ColorPrimary),
ContextCompat.getColor(context, com.yanzhenjie.album.R.color.album_ColorPrimaryDark))
.build()
)
.build();
}
好吧,并没有调用,只是设置标题栏而已,点击返回或者确定,内部自己就会监听,给我们回调。
3、完成了图片的添加和显示,接着就需要考虑到图片的上传了。。。
使用到了AsyncTask(总体代码)
private class MyTask extends AsyncTask<Object, Object, RequestParams> {
@Override//对上传的数据进行处理
protected RequestParams doInBackground(Object... params) {
PurchaseParamsBean purchaseParamsBean = new PurchaseParamsBean();
purchaseParamsBean.setPurchaseFiles(getAllBase64Img());
RequestParams requestParams = new RequestParams();
requestParams.add("Source", 2 + "");
requestParams.add("tokenID", SPUtils.get(context, Constants.tokenID, "").toString());
requestParams.add("OpenId", "");
String value = new Gson().toJson(purchaseParamsBean);
requestParams.add("PurchaseParams", value);
for (int i = 0; i < mAdapter.getDatas().size(); i++) {
try {
String path = mAdapter.getDatas().get(i).getPath();
if (!TextUtils.isEmpty(path)) {
requestParams.put("files" + i, CompressUtil.getCompressPic(path, getCacheDir().getPath()));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
return requestParams;
}
//进行网络请求
@Override
protected void onPostExecute(RequestParams requestParams) {
sendRequest(Http_Url.InsertHirePurchase, requestParams, OnlyIntModelBean.class, "", false, btn_perfectdata_submit, new BaseCallBack<OnlyIntModelBean>() {
@Override
public void onSuccess(OnlyIntModelBean onlyIntModelBean) {
if (onlyIntModelBean != null) {
if (onlyIntModelBean.getStatu() == 1) {
ToastL.show("预订成功");
AbsUI.startUI(context, MyOrderUI.class);
mAdapter.getDatas().clear();
mAdapter = null;
mRv = null;
stopUI(ui);
} else if (onlyIntModelBean.getStatu() == -2) {
ToastL.show(onlyIntModelBean.getMsg());
// StringUtils.IsOUTOFtime(context, OnlineBookingUI3.this.ui);
} else {
ToastL.show(onlyIntModelBean.getMsg());
}
}
}
}
(代码解析)
我们一步步看,PurchaseParamsBean 里添加了图片组的字段,用一个ArrayList在表示
public class PurchaseParamsBean {
。。。
public ArrayList purchaseFiles= null;//附件
public ArrayList getPurchaseFiles() {
return purchaseFiles;
}
public void setPurchaseFiles(ArrayList purchaseFiles) {
this.purchaseFiles = purchaseFiles;
}
。。。
}
在AysnTask里对purchaseFiles赋值了。
purchaseParamsBean.setPurchaseFiles(getAllBase64Img());
public ArrayList<String> getAllBase64Img() {
ArrayList<String> arr = new ArrayList<>();
for (AlbumFile file : mAdapter.getDatas()) {
if (!TextUtils.isEmpty(file.getPath())) {
arr.add(getBase64String4Loader(file.getPath()));
}
}
if (arr.size() == 0) {
return null;
} else {
return arr;
// return new Gson().toJson(arr);
}
}
/**
* 创建图片数组---通过ImageLoader
*
* @return
*/
private String getBase64String4Loader(Object tag) {
Bitmap bitmap = null;
if (tag instanceof Uri) {// 取出本地uri
Uri uri = (Uri) tag;
Log.e(TAG, "uri:" + uri.toString());
bitmap = CompressUtil.getimage(BitmapUtils.getImageAbsolutePath(
OnlineBookingUI3.this, uri));
} else {
// 取出绝对路径(从路径里解析出文件类型)
String path = (String) tag;
Log.e(TAG, "path:" + path);
bitmap = CompressUtil.getimage(path);
}
byte[] bytes = CompressUtil.compressImage(bitmap);
Log.e(TAG, bytes.length + "");
String base64 = Base64.encodeToString(bytes, Base64.DEFAULT);
// 回收
bitmap.recycle();
Log.e(TAG, "getBase64String4Loader回收了bitmap");
return base64;
}
最终将url转化成了一种字符串,base64编码,有兴趣的可以了解
sendRequest的实现
public <T> void sendRequest(String url, RequestParams param, final Class<T> clazz, String showText, boolean isdialogShow, View view, final BaseCallBack<T> baseCallBack) {
if (null == param) param = new RequestParams();
AsyncCallBackHandler res = new AsyncCallBackHandler(ui, showText, isdialogShow, view) {
@Override
public void mySuccess(int arg0, Header[] arg1, String arg2) {
String s = arg2;
if (arg2.startsWith("<?xml") || arg2.startsWith("<string")) {
s = parseXMLwithPull(arg2);
}
// Bean bean = GJson.parseObject(s, Bean.class);
T t = null;
try {
// t = new Gson().p(s, clazz);
t = new Gson().fromJson(s, clazz);
} catch (Exception e) {
e.printStackTrace();
baseCallBack.onFailure("json解析异常", new IllegalStateException("json解析异常"));
}
baseCallBack.onSuccess(t);
}
@Override
public void myFailure(int arg0, Header[] arg1, String arg2, Throwable arg3) {
baseCallBack.onFailure(arg2, arg3);
}
@Override
public void onStart() {
super.onStart();
baseCallBack.onStart();
}
@Override
public void onFinish() {
super.onFinish();
baseCallBack.onFinish();
}
};
AsyncHttpUtil.post(url, context, param, res);
}
最终会回调上面的onsUCCESS
AsyncHttpUtil.post(url, context, param, res);的实现
/**
* post已key,value形式传参,返回一个字符串数据
*
* @param urlString
* @param params
* @param res
*/
public static void post(String urlString, Context context, RequestParams params, AsyncHttpResponseHandler res) // url里面带参数
{
NetworkState state = new NetworkState(context);
if (state.isConnected() == false) {
Prompt.showWarning(context, "请检查您的网络");
return;
}
client.post(urlString, params, res);
}
这主要是要注意格式,回调,图片压缩,这几方面