Espresso测试重启后出现No persistable permission grants found for UID错误的解决方法
Espresso测试重启后出现持久化权限错误
应用权限请求与持久化实现
应用通过以下代码请求文件夹访问权限:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); intent.putExtra("android.provider.extra.SHOW_ADVANCED", true); mStartChooseFolderForResult.launch(intent);
在onActivityResult中处理权限持久化:
public void onActivityResult(ActivityResult result) { if (result.getResultCode() == Activity.RESULT_OK) { Intent intent = result.getData(); Uri uri = intent.getData(); ContentResolver cr = getActivity().getContentResolver(); int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION; cr.takePersistableUriPermission(uri, flags); ... } }
测试代码
Espresso测试中模拟文件夹选择结果:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); intent.setData(Uri.parse(DEFAULT_FOLDER_STRING + "%2F" + testFolder)); Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(Activity.RESULT_OK, intent); intending(hasAction(Intent.ACTION_OPEN_DOCUMENT_TREE)).respondWith(result); onView(withText("select")).perform(click());
问题现象
- 手动运行应用时,持久化权限正常生效,重启设备后权限仍保留。
- 设备重启后直接运行Espresso测试,抛出错误:
No persistable permission grants found for UID... - 若先手动打开应用选择测试指定文件夹,再运行测试则无异常。
解决方法
问题根源在于测试中仅模拟了Uri返回,但未触发系统层面的持久化权限授予流程——手动操作时系统会自动为选中的Uri临时授予权限,再通过takePersistableUriPermission转为持久化权限;而Espresso模拟的Intent结果没有附带权限标记,导致takePersistableUriPermission无法生成有效持久化权限。
可以通过以下两种方式解决:
方式1:在测试中手动添加权限标记
修改模拟返回的Intent,添加临时权限标记,确保takePersistableUriPermission能正常持久化:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); Uri folderUri = Uri.parse(DEFAULT_FOLDER_STRING + "%2F" + testFolder); intent.setData(folderUri); // 为Intent添加临时权限标记 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(Activity.RESULT_OK, intent); intending(hasAction(Intent.ACTION_OPEN_DOCUMENT_TREE)).respondWith(result);
方式2:在测试中直接授予持久化权限
如果模拟Intent仍无法解决,可在测试初始化阶段,直接通过Instrumentation调用ContentResolver授予持久化权限:
@Before public void setUp() { // 初始化测试环境 Uri folderUri = Uri.parse(DEFAULT_FOLDER_STRING + "%2F" + testFolder); ContentResolver cr = InstrumentationRegistry.getInstrumentation().getTargetContext().getContentResolver(); int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION; // 先尝试移除已有权限(避免重复授予报错) try { cr.releasePersistableUriPermission(folderUri, flags); } catch (Exception e) { // 无权限时忽略异常 } // 授予持久化权限 cr.takePersistableUriPermission(folderUri, flags); }
额外注意事项
- 确保测试设备的API版本与应用目标版本一致,不同版本的Uri权限处理逻辑可能有差异。
- 若使用Android 11+,需注意
MANAGE_EXTERNAL_STORAGE权限与SAF权限的兼容性,但此问题中核心是SAF的持久化权限,因此无需额外申请该权限。
内容的提问来源于stack exchange,提问作者Laurent D.
相关产品推荐
相关产品推荐

