日常爬坑-android uri 生命周期问题
最近在写我的个人应用KeepassA时,遇到了android文件uri生命周期的问题,被文件真实路径的获取搞得有点懵逼。从android p开始,谷歌对文件访问的权限限制的更加变态了,如果想兼容大多数机型,使用谷歌提供的ASF框架是一个很好的选择。
但是该框架只能返回文件的uri
,并不能返回文件路径,并且随着android的进一步升级,特别是从android Q 开始,已经完全无法从uri获取到文件真实路径了!!
一、uri 过期
出现的异常有:
java.lang.SecurityException: Permission Denial: opening provider com.android.externalstorage.ExternalStorageProvider |
原因:
1、如果你通过AFS获取文件uri使用Intent.ACTION_OPEN_DOCUMENT
或Intent.ACTION_GET_CONTENT
时,系统只会给你一个临时的uri访问权限,当你的设备重新启动后,该uri就没有了权限。
如:
Intent.ACTION_GET_CONTENT |
解决方案:
https://developer.android.google.cn/training/data-storage/shared/documents-files#persist-permissions
向android系统请求长期权限
val takeFlags: Int = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
注意:该请求需要在onActivityResult
申请
2、自己拼接的uri 没有设置
如果不是访问文件的uri,那么你需要手动设置authority
二、No persistable permission grants
原因:一般是手动Uri.Builder
导致的问题,系统不认该uri。
如:
val temp = Uri.parse(uriString) |
三、获取已授权的Uri
即使我们申请了长期的uri权限,但是如果该uri对应的文件或uri被移动或删除了,应用依然会删除该uri的权限,需要重新申请uri权限。因此,在每次使用uri打开文件时,最好检查应用是否还保留该uri的权限。
获取已授权的的uri列表:
val list = context!!.contentResolver.persistedUriPermissions |
日常爬坑-android uri 生命周期问题