Android手机调用系统相机拍照或者选择本地相册图片,然后剪裁上传服务器,应该是很常见的操作了。网上一搜一大堆开源第三方框架可以用,由于本次项目这块功能比较简单,就自己实现了,本来都是常规操作,但是写着写着就遇到了很多问题,比如获取相册图片7.0以上系统的适配问题,某些手机拍照之后照片自动旋转的问题,某些手机剪裁之后图片有黑边的问题等等,好在这些问题都有网上很多大神提供了解决方案。
但是最后碰到了一个很诡异的问题,就是小米Max2手机剪裁好图片以后上传服务器失败,试过其他很多牌子手机都没问题,查看了报错信息,java.net.ProtocolException: expected 215 bytes but received 8192。第一反应是不是图片太大了,然后试了下剪裁到很小,依然是同样的报错,而且215和8192两个数字都没变,所以应该不是图片大小的问题。
然后开始了各种打断点调试,发现在调用上传接口之前断点等几秒钟再执行,就可以上传成功。难道是剪裁的图片资源还没生成好?然后我在剪裁图片的回调方法里延时了几秒钟在调用上传接口,结果无论我延时多久,还是上传失败。明明剪裁回调返回的Uri是有值的,为什么会失败呢?而且断点延时执行上传就可以,写代码延时执行上传接口就不行!!
最后,突然灵机一动,既然你剪裁回调给的Uri不能用,那我就自己再保存本地一次,用我自己保存的这个路径去上传。结果还真的可以了。
下面是处理的代码片段:
case RESULT_CROP:
String path = mPhotoUtils.getCropPath();
if (!TextUtils.isEmpty(path)) {
//解决某些手机(小米MI MAX2)虽然能从上面的path中拿到图片,但是这时候拿这个path中取到的图片上传会上传失败。(应该是系统还在对这个path做一些异步的处理操作)
String url = mPhotoUtils.compressImg(getContext(), path);
if (!TextUtils.isEmpty(url)) {
presenter.uploadPic(new File(url), mImgType);
showProgressDialog("图片上传中");
}
}
break;
mPhotoUtils是自己写的拍照和选取相册,并且剪裁的工具类,path就是剪裁之后的图片所在的本地路径,然而这个路径在小米Max2手机上就是不能用来上传服务器。String url = mPhotoUtils.compressImg(getContext(), path);
这行代码就是拿上面获取到的path重新压缩存储了一遍,并返回重新存储的路径,拿这个路径下的图片上传就可以了。
后来又发现某些手机这样处理还是有问题,比如vivo某个型号的手机,解决办法是拿到剪裁路径path之后,对path做一下应用,Bitmap image = BitmapFactory.decodeFile(path);然后判断image是否为空,如果空的话就延迟一段时间在拿这个路径去上传。具体代码片段如下:
String path = mPhotoUtils.getCropPath();
if (!TextUtils.isEmpty(path)) {
Bitmap image = BitmapFactory.decodeFile(path);
if (image == null){
//解决ViVo Y67L 手机的问题
showProgressDialog("图片上传中");
HandlerUtil.postDelay(new Runnable() {
@Override
public void run() {
String url = mPhotoUtils.compressReSave(path, getContext());;
if (!TextUtils.isEmpty(url)) {
presenter.uploadPic(new File(url), mImgType);
} else {
ToastUtils.showShortToast(getContext(), "图片加载失败,请拍照重试");
}
}
}, 1000);
} else {
//解决某些手机(小米MI MAX2)虽然能从上面的path中拿到图片,但是这时候拿这个path中取到的图片上传会上传失败。(应该是系统还在对这个path做一些异步的处理操作)
String url = mPhotoUtils.compressReSave(path, getContext());;
if (!TextUtils.isEmpty(url)) {
presenter.uploadPic(new File(url), mImgType);
showProgressDialog("图片上传中");
} else {
ToastUtils.showShortToast(getContext(), "图片加载失败,请拍照重试");
}
}
最后附上工具类PhotoUtils下载地址:https://github.com/androidliuzemin/photoUtils