适配Android11之后更改了图片保存目录,导致裁剪之后图片一直无法加载(fileNotfound)
最主要的问题在于保存裁剪文件的目录不能为私有目录,因为裁剪工具是系统工具,无法直接访问项目本身的私有目录。
解决办法:把裁剪后保存的目录改为公有目录,亲测可用。
if (uri != null) {
currentPath = "";
currentPath = System.currentTimeMillis() + ".jpg";
File file = new File(Environment.getExternalStoragePublicDirectory(DIRECTORY_PICTURES) + currentPath);
imageCropUri = Uri.fromFile(file);
Intent intent = new Intent("com.android.camera.action.CROP");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
intent.setDataAndType(uri, "image/*");
// 设置裁剪
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
// outputX outputY 是裁剪图片宽高
intent.putExtra("outputX", 150);
intent.putExtra("outputY", 150);
//裁剪之后,保存在裁剪文件中,关键
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageCropUri);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true);
intent.putExtra("return-data", false);
startActivityForResult(intent, CODE_RESULT_REQUEST);
}
还有一个问题是拍照之后保存的图片位置,不能放在私有目录的二级目录下,可以放在根目录
比如说私有目录的根目为
/storage/emulated/0/Android/data/packageName/files
直接保存在根目录下加载图片是没有问题的
但是如果保存在二级目录下
/storage/emulated/0/Android/data/packageName/files/test
会提示加载图片失败
case CODE_CAMERA_REQUEST://拍照
File file = new File(MyPathUtil.getPrivatePath(null), IMAGE_FILE_NAME);
Uri imageUri;
if (hasSdcard()) {
File tempFile = new File(MyPathUtil.getPrivatePath(null), IMAGE_FILE_NAME);
//获取图片旋转角度
int bitmapDegree = MineImageUtils.getBitmapDegree(tempFile.getAbsolutePath());//获取图片选择角度
//若图片的旋转角度不是0
if (bitmapDegree != 0) {
Bitmap nowBitmap = MineImageUtils.rotaingImageView(bitmapDegree, BitmapFactory.decodeFile(tempFile.getPath()));
//bitmap转uri
Uri uri = Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(), nowBitmap, null, null));
startPhotoZoom(uri);
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
imageUri = MyFileProvider.getUriForFile(this, packageName + ".fileprovider", file);//通过FileProvider创建一个content类型的Uri
} else {
imageUri = Uri.fromFile(file);
}
startPhotoZoom(imageUri);
}
} else {
showToast("没有SDCard!");
}
break;
/**
* 获取下载路径 类型为以上静态变量 可为null
*
* @param type
* @return
*/
public static String getPrivatePath(String type) {
if (android.os.Build.VERSION.SDK_INT < 30) {
if (TextUtils.isEmpty(type)) {
return privatePath;
} else {
return privatePath + "/" + type;
}
} else {
//该方法可传一个String类型的参数,表述为该路径下的文件夹,没有该文件夹会自动创建 可传null
return AppApplication.mContext.getExternalFilesDir(type).getAbsolutePath();
}
}
private static String privatePath = Environment.getExternalStorageDirectory().getPath() + "/Android/data/" + AppUtils.getAppPackageName() + "/files";
参考https://codeleading.com/article/90075423256/