SecurityException:Permission Denial:opening provider com.android.providers...DownloadStorageProvider

环境

Android Studio Arcttic Fox, 测试机版本 Android 10

问题描述

在使用 registerForActivityResult 结合 ActivityResultContracts.OpenDocument() 获取到文件 Uri 后,直接使用 和 保存到 SharePreference 后,用如下两种调用方式获取文件名称,和用于读取文件内容均正常。

DocumentFile.fromSingleUri(requireActivity(),uri).getName();
getContentResolver().openInputStream(uri);

但是,测试发现,在将手机重启后,再从 SharePreference 中取出保存的 Uri,使用上面两种方式均失败。前者为空,后者崩溃并报异常:

java.lang.SecurityException: Permission Denial: opening provider
 com.android.providers.downloads.DownloadStorageProvider

问题分析

解决问题优先,所以先面向百度编程,有两种方案:

  1. 既然提示是权限不够,所以很多方案都是要求添加 andriod.permission.WRITE_EXTERNAL_STORAGEandroid.permission.READ_EXTERNAL_STORAGE 权限,但代码中早就添加了。
  2. 其次很多方案是适配kitkat, 本项目已经最小目标版本是21,也不适用。

考虑到只有重启手机后才会报错,而单纯重启APP不会,那么很大概率在于调用 ActivityResultContracts 时系统临时赋予了权限,重启手机后所有临时权限都会自动取消。至于要求的是什么权限,还不清楚。继续查找

在 Android Studio 里面,将鼠标放到 DocumentFile.fromSingleUri(requireActivity(), uri).getName() 上时,提示框中显示 fromSingleUri() 的 singleUri 参数信息:

 @params: singleUri - the Intent.getData() from a successful Intent.
               ACTION_OPEN_DOCUMENT or Intent.ACTION_CREATE_DOCUMENT request.

这里可看到,需要 Intent.ACTION_OPEN_DOCUMENTIntent.ACTION_CREATE_DOCUMENT。我这里是读取文件内容,那肯定是前者。现在问题是在哪里加这个 Action。继续查找

回到谷歌官方文档,先看下文档 DocumentFile 下的说明,没有看到有用信息。再看方法 fromSingleUri(),也没有。再进入到 Intent.ACTION_OPEN_DOCUMENT。看到了如下说明:

 All selected documents are returned to the calling application with persistable read 
 and write permission grants.If you want to maintain access to the documents across 
 device reboots, you need to explicitly take the persistable permissions using  
 ContentResolver#takePersistableUriPermission(Uri, int). 

答案出来了,果如所料,这里说如果要求在重启设备后仍然能够访问文档。需要使用 ContentResolver#takePersistableUriPermission(Uri, int) 来显式地获取持久许可。

问题解决

使用 registerForActivityResult 结合 ActivityResultContracts.OpenDocument() 获取到文件 Uri 后,调用

getCntentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);

获取持久许可。

参考文献

[1] 官方文档 - Intent#ACTION_OPEN_DOCUMENT

猜你喜欢

转载自blog.csdn.net/dpdcsdn/article/details/123015667