2018-07-18
生命不息,奋斗不止,万事起于忽微,量变引起质变 -------- Hongyang
敲黑板、这是重点
1. inputUri 是 Content URI 需要适配 7.0
2. outputUri 并没有改变,仍然使用的是 Uri.fromFile()
调用系统裁剪
调用系统裁剪的过程中涉及到两个 Uri 对象:inputUri 和 outputUri,较为复杂一些。通常,调用系统裁剪的来源为调用系统拍照或选择系统相册。前者返回的是一个 File URI 对象,后者返回的是一个 Content URI 对象。作为裁剪源,我们要做的就是对其做进一步处理。但是不能像上面那样使用 getUriForFile()
方法,这个并不难理解,因为如果是选择系统相册所得的图片,本身也不一定属于我们自己的应用。正确处理方式是这样:
private Uri getImageContentUri(String path){
Cursor cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.Media._ID},
MediaStore.Images.Media.DATA + "=? ",
new String[]{path}, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor.getColumnIndex(MediaStore.Images.Media._ID));
Uri baseUri = Uri.parse("content://media/external/images/media");
return Uri.withAppendedPath(baseUri, ""+id);
}else {
ContentValues contentValues = new ContentValues(1);
contentValues.put(MediaStore.Images.Media.DATA, path);
return getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
}
}
拿到正确的 Content URI 后,作为 inputUri,传递给 Intent 对象:
Intent intent = new Intent("com.android.camera.action.CROP");
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(inputUri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(outputFile));
startActivityForResult(intent, REQUEST_PICK);
注意:这里的 outputUri 并没有改变,仍然使用的是 Uri.fromFile()
方法获取的 File URI 类型!这是很奇怪的一点,但是不得不这么做。事实上,使用这种方式调用系统裁剪功能本身就是有问题的!常见问题如:在部分机型上,调用系统裁剪并返回前一个页面时,在 onActivityResult() 方法中得到的 resultCode 值不等于 RESULT_OK。Crop Intent 在官方文档中本来就无迹可寻,本身就是一种不推荐的用法!取而代之的是,我们可以使用 GitHub 上的一些开源库实现应用内的图片裁剪功能,比如 uCrop、cropper 等。
摘自: 亦枫
Android 7.0 provider属性说明
关于 Android 7.0 适配中 FileProvider 部分的总结