问题描述
我仅在 Android 10 中遇到图像权限问题。我声明该问题仅适用于 android 10,实际上在 android 11 和 android 9 及更早版本中启用了写入和读取权限。
如文档所述,在清单中我有 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxsdkVersion="28"/>
和应用程序 android:requestLegacyExternalStorage="true"
。
我的编译版本是 30,目标是 30。即使将目标版本恢复到 29,我也得到了相同的结果。
通过意图插入文件:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
photoUri = activity.getContentResolver().insert(
MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL),contentValues
);
else
photoUri = activity.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues
);
final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,photoUri);
activity.startActivityForResult(intent,REQUEST_CAMERA_KEY);
取而代之的是这样的:
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data) {
super.onActivityResult(requestCode,resultCode,data);
if (requestCode != REQUEST_CAMERA_KEY || resultCode != RESULT_OK)
return;
// use imagedecoder.decodeBitmap >= Build.VERSION_CODES.P
final Bitmap bitmap =BitmapProvider.getBitmap(contentResolver,photoUri);
Cursor cursor = contentResolver.query(photoUri,null,null);
String value = null;
if (cursor == null) {
value = photoUri.getPath();
} else {
cursor.movetoFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
value = cursor.getString(idx);
}
cursor.close();
File file = new File(value);
// Android 9 and < true true
// Android 10 false false
// Android 11 true true
System.out.println(file.canRead() + " " + file.canWrite());
try {
final FileOutputStream fileOutputStream = new FileOutputStream(file); // Android 10 generate open Failed: EACCES (Permission denied) exception
bitmap.compress(Bitmap.CompressFormat.JPEG,90,fileOutputStream);
} catch (FileNotFoundException e) {
e.printstacktrace();
}
}
获取位图:
public Bitmap getBitmap(
final ContentResolver contentResolver,final Uri photoUri){
Bitmap bitmap = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
final imagedecoder.source source = imagedecoder.createSource(contentResolver,photoUri);
try {
bitmap = imagedecoder.decodeBitmap(source);
} catch (IOException e) {
e.printstacktrace();
}
} else {
InputStream inputStream = null;
try {
inputStream = contentResolver.openInputStream(photoUri);
bitmap = BitmapFactory.decodeStream(inputStream);
} catch (FileNotFoundException e) {
e.printstacktrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printstacktrace();
}
}
}
}
return bitmap;
}
尽管遵循了文档,但我仍需要对此进行解释,也许还需要解释。谢谢。
解决方法
如果您请求旧存储,则还必须获得存储许可:
android:requestLegacyExternalStorage="true"
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
。
如果您面向 API 30 requestLegacyExternalStorage
不起作用。您需要将目标 SDK 设置为 29 或使用媒体存储 API。