重启Android应用时打开MediaDocumentsProvider遭遇权限拒绝问题求助
解决重启应用后访问MediaDocumentsProvider权限被拒的问题
嘿,我来帮你搞定这个重启应用后访问图片权限被拒的问题!这个问题的核心原因其实很简单:你当前用ACTION_GET_CONTENT和ACTION_PICK获取的图片Uri,系统只给了临时访问权限,一旦应用重启,这个临时权限就失效了,自然就会触发权限拒绝的错误。下面给你分步解决的方案:
1. 替换Intent为支持持久化权限的类型
ACTION_GET_CONTENT和ACTION_PICK不支持持久化权限,我们需要换成ACTION_OPEN_DOCUMENT——这是Android官方推荐的用于获取可持久访问文件的Intent。修改你的pickImage方法:
public void pickImage(View view) { Intent openDocumentIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT); openDocumentIntent.setType("image/*"); // 指定只选择可打开的文件 openDocumentIntent.addCategory(Intent.CATEGORY_OPENABLE); Intent chooserIntent = Intent.createChooser(openDocumentIntent, "Select Image"); // 如果你用的是旧的onActivityResult,就startActivityForResult;用Jetpack的话就用Activity Result API pickImageLauncher.launch(chooserIntent); }
2. 获取并保存持久化权限
在获取到图片Uri的回调里,调用ContentResolver.takePersistableUriPermission()把临时权限转为持久化权限,这样重启应用后依然能访问。
如果你用Jetpack的Activity Result API:
// 先注册Launcher ActivityResultLauncher<Intent> pickImageLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == RESULT_OK && result.getData() != null) { Uri imageUri = result.getData().getData(); if (imageUri != null) { // 提取Intent中的权限flags int takeFlags = result.getData().getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); // 申请持久化权限 getContentResolver().takePersistableUriPermission(imageUri, takeFlags); // 把Uri保存到SharedPreferences或数据库,供重启后使用 saveImageUri(imageUri.toString()); } } } );
如果你用旧的onActivityResult:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK && data != null) { Uri imageUri = data.getData(); if (imageUri != null) { int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); getContentResolver().takePersistableUriPermission(imageUri, takeFlags); saveImageUri(imageUri.toString()); } } }
3. 保存Uri并在重启后读取
把获取到的Uri字符串保存起来,重启后直接读取使用就行:
// 保存Uri到SharedPreferences private void saveImageUri(String uriStr) { SharedPreferences prefs = getSharedPreferences("AppSettings", MODE_PRIVATE); prefs.edit().putString("PROFILE_IMAGE_URI", uriStr).apply(); } // 重启后读取Uri private Uri getSavedImageUri() { SharedPreferences prefs = getSharedPreferences("AppSettings", MODE_PRIVATE); String uriStr = prefs.getString("PROFILE_IMAGE_URI", null); return uriStr != null ? Uri.parse(uriStr) : null; }
注意事项
- 只有
ACTION_OPEN_DOCUMENT和ACTION_OPEN_DOCUMENT_TREE支持持久化权限,其他Intent类型不行,所以一定要替换。 - 如果用户卸载重装应用,之前保存的持久化权限会失效,需要重新让用户选择图片。
- 如果你只需要读取图片,只申请
FLAG_GRANT_READ_URI_PERMISSION就够了,不需要写权限。
内容的提问来源于stack exchange,提问作者Arturo Pavón
相关产品推荐
相关产品推荐

