在Android14+以上,申请 Manifest.permission.READ_MEDIA_IMAGES 权限时,会弹出以下权限框。

这是在Android 14新增的细化权限,参考链接:Google
当用户选择“选择照片和视频”而不是“全部允许”时,会丢失 READ_MEDIA_IMAGES 权限,因此在适配安卓14时,需要检测 READ_MEDIA_IMAGES 和 READ_MEDIA_VISUAL_USER_SELECTED 权限,第二个是用户选择“选择照片和视频”时会授权的。
按照谷歌的建议,可以使用Photo Picker 来获取图片或视频文件Uri。
public void init(){
ActivityResultLauncher<PickVisualMediaRequest> launcher = ((AppCompatActivity) mContext).registerForActivityResult(new ActivityResultContracts.PickVisualMedia(), new androidx.activity.result.ActivityResultCallback<Uri>() {
@Override
public void onActivityResult(Uri result) {
LogUtils.e("result:" + result);
}
});
}
public void show(){
PickVisualMediaRequest.Builder builder = new PickVisualMediaRequest.Builder()
.setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE);
launcher.launch(builder.build());
}
需要引用androidx.activity
api 'androidx.activity:activity:1.9.1'
如果需要解析成 Bitmap 或者 File ,可以参考以下代码
public void toBitmap(Uri uri){
ImageDecoder.Source source = ImageDecoder.createSource(mContext.getContentResolver(), uri);
Bitmap bitmap = ImageDecoder.decodeBitmap(source);
}
public boolean saveBitmap(Bitmap bitmap, File imageFile) {
boolean success = false;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
saveImageInfo(imageFile);
success = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return success;
}
/**
* 把视频保存到ContentProvider,在选择上传的时候能找到
*/
private void saveImageInfo(File file) {
try {
String fileName = file.getName();
long currentTimeMillis = System.currentTimeMillis();
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.TITLE, fileName);
values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName);
values.put(MediaStore.MediaColumns.DATE_MODIFIED, currentTimeMillis);
values.put(MediaStore.MediaColumns.DATE_ADDED, currentTimeMillis);
values.put(MediaStore.MediaColumns.DATA, file.getAbsolutePath());
values.put(MediaStore.MediaColumns.SIZE, file.length());
values.put(MediaStore.MediaColumns.MIME_TYPE, "image/png");
CommonAppContext.sInstance.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} catch (Exception e) {
e.printStackTrace();
}
}
参考文档:
https://developer.android.com/training/data-storage/shared/photopicker?hl=zh-cn
https://developer.android.com/about/versions/14/changes/partial-photo-video-access?hl=zh-cn