我仅在 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);
相反, get 是这样发生的:
@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, 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;
}
尽管遵循了文档,但我仍然需要对此进行解释,也许还需要一个解释。感谢。