完整的demo地址,包括动态权限申请,FileProvider使用,华为部分机型根据uri拿不到真实路径,魅族部分机型裁剪失败.
用户反馈,在魅族手机,裁剪照片一直失败,app的正常需求是选择照片,然后去裁剪,裁剪完,显示出来,但是有的用户选择完照片没有去裁剪。
经过调试,发现,选择照片这一步是没问题的,但是在去调用系统的裁剪的时候,resultCode 为0,且data一直为null.其实,魅族手机调用系统的拍照,返回的data也是null,但是至少resultCode是1 也就是Result_OK 这个的解决办法需要我们调用系统拍照的时候,传入一个路径就可以解决(详情请见下面的demo)但是选择照片去裁剪的时候,resultCode直接是0,经过调试,选择照片是可以正常拿到图片地址的,只是裁剪的时候,被取消了,仔细对比了下,只有在选择文件管理下的图片才会有这种情况,例如选择最近目录下的图片,就会出现这种情况,仔细看了下,选择图片返回的路径格式为:
content://com.android.providers.media.documents/document/image%3A1229
普通的图库选择的图片返回的路径为:
content://media/external/images/media/2681269
问题就出在这个路径上面,经过测试,华为手机的系统裁剪是可以正常找到图片,并加载出来,可是魅族(我测试用的是Android9.0)的部分机型就加载不出来,会找不到图片。
解决办法:
先根据这个文件管理的虚拟uri,拿到真实的图片地址,因为系统裁剪需要一个uri,故这里我们需要把这个真是路径地址,再次转成uri.再传给裁剪,就可以正常加载了。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.e("zmm", "reque:" + requestCode + "result:" + resultCode + "data:" + (data == null));
if (data != null) {
Log.e("zmm", "data:value:" + data.getStringExtra("filePath"));
Log.e("zmm", "data:value:" + data.getData());
}
//if(data!=null){
// Log.e("zmm","data:value:"+data.getData());
//}
if (resultCode == RESULT_OK) {
switch (requestCode) {
case IMAGE_REQUEST_CODE://选择图片成功返回
if (data != null && data.getData() != null) {
imageUri = data.getData();
//根据uri拿到真实路径
String path = ImageUtils.getPath(this, imageUri);
File file = new File(imageUri.getPath());
Log.e("zmm", "选择的图片的虚拟地址是------------>" + data.getData() + "--->" +
path + "--->" + file.getAbsolutePath());
//根据真实路径生成一个uri
imageUri = ImageUtils.getUri(this, path);
Log.e("zmm", "转换以后的路径:" + imageUri);
crop(imageUri, getOutCropUri());
}
break;
case CROP_REREQUEST_CODE:
Log.e("zmm", "裁剪以后的地址是------------>" + cropUri);
//裁剪成功,显示出来.
decodeImage(cropUri);
break;
}
}
}
private void crop(Uri inUri, Uri outUri) {
if (inUri == null) {
return;
}
Intent intent = new Intent("com.android.camera.action.CROP");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(inUri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", aspectX);
intent.putExtra("aspectY", aspectY);
intent.putExtra("scale", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outUri);
intent.putExtra("return-data", false);
intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());
intent.putExtra("noFaceDetection", true);
if (intent.resolveActivity(getPackageManager()) != null) {
Log.e("zmm", "安装了裁剪程序...");
startActivityForResult(intent, CROP_REREQUEST_CODE);
} else {
// 没有安装所需应用
Log.e("zmm", "没有安装所需应用...");
}
}
至于具体原因,需要去看下魅族手机的源码,我估计是在系统的裁剪里面,无法识别出文件管理里面的图片所产生的的uri.故拿不到文件,直接取消了裁剪.
每日语录:
只管努力,剩下的交给时间.加油!!!
单曲循环《再见悲哀》