使用OpenDocument()获取的文件如何正确授权以支持重启后正常打开?
问题原因
你遇到的权限失效是Android系统URI授权机制的正常逻辑:
- 调用
OpenDocument()选中文件时,系统仅给你的应用授予临时URI访问权限,该权限有效期仅持续到当前应用进程终止 - 应用重启后临时权限被系统自动回收,你之前存储的URI就失去了访问权限,因此抛出
SecurityException - 你在跳转打开文件时添加的
FLAG_GRANT_READ_URI_PERMISSION,是用来给你跳转的第三方查看应用授予权限,不会给你的自身应用持久化保留权限
修复方案
在拿到OpenDocument()返回的URI时,主动向系统申请该URI的持久化访问权限即可,系统会永久保留该授权,直到你主动释放或者文件被删除。
你只需要在OpenDocument()的回调中,拿到URI后新增一行申请持久化权限的代码:
contentResolver.takePersistableUriPermission( it, Intent.FLAG_GRANT_READ_URI_PERMISSION )
如果你的应用后续需要修改该文件,可以同时申请写权限:
contentResolver.takePersistableUriPermission( it, Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION )
完整修改后的回调代码
val getFile = registerForActivityResult( ActivityResultContracts.OpenDocument() ) { if (it != null) { // 新增:申请URI持久化访问权限 contentResolver.takePersistableUriPermission( it, Intent.FLAG_GRANT_READ_URI_PERMISSION ) val fileLink = FileLink() fileLink.setUri(it.toString()) fileLink.setType(contentResolver.getType(it)!!) fileLink.setName(getFileName(it)!!) list.add(fileLink) presenter.saveChangesToList(list) adapter.notifyDataSetChanged() } }
补充说明
- 该API仅在Android 4.4(API 19)及以上版本支持,符合当前绝大多数应用的适配要求
- 如果你后续需要移除某个文件的访问权限,可以调用
contentResolver.releasePersistableUriPermission(uri, flag)主动释放 - 每次应用启动后如果要校验权限是否存在,可以通过
contentResolver.persistedUriPermissions查询已获得持久化授权的URI列表
内容的提问来源于stack exchange,提问作者Javier Takano
相关产品推荐
相关产品推荐

