问题描述
我的应用通过ACTION_PICK意图收集媒体以获取
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI
内容类型。当我检索想要的内容的URI时,它可以很好地工作,并且可以通过以下方式查看它:
val intent = Intent(Intent.ACTION_VIEW,myURI)
intent.setDataAndType(myURI,contentResolver.getType(myURI))
intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION)
startActivity(intent)
我使用Uri.toString
方法存储Uri,一旦我关闭活动并再次打开它,就会出现以下错误:
java.lang.SecurityException: UID 10315 does not have permission to content://com.miui.gallery.open/raw/%2Fstorage%2Femulated%2F0%2FDCIM%2FCamera%2FVID_20200814_214253.mp4 [user 0]
再往下走:
Caused by: android.os.RemoteException: Remote stack trace:
at com.android.server.uri.UriGrantsManagerService.checkGrantUriPermission(UriGrantsManagerService.java:1192)
at com.android.server.uri.UriGrantsManagerService.checkGrantUriPermissionFromIntent(UriGrantsManagerService.java:579)
at com.android.server.uri.UriGrantsManagerService.grantUriPermissionFromIntent(UriGrantsManagerService.java:618)
at com.android.server.uri.UriGrantsManagerService$LocalService.grantUriPermissionFromIntent(UriGrantsManagerService.java:1392)
理想情况下,我将获取媒体的文件路径并通过fileProvider从文件生成URI,但是我还没有找到从ContentURIs获取绝对路径的方法。
通读https://commonsware.com/blog/2016/08/10/uri-access-lifetime-shorter-than-you-might-think.html可以更好地解释正在发生的事情,那么如何重用或存储通过URI检索到的文件?我可以通过某种方式检索文件路径而不是URI吗?
解决方法
我使用Uri.toString方法存储Uri
那是行不通的。您对从ACTION_PICK
获得的内容的权利为very short-lived。 (请注意:此链接指向您在问题中链接到的我的博客文章的较新版本)
理想情况下,我会获取媒体的文件路径
那也行不通。不需要ACTION_PICK
或类似的操作来返回与文件系统有关的任何内容,更不用说返回可以直接访问的文件了。在您的特定情况下,MediaStore
的访问权限要比您更大,因此即使您查询半弃用的MediaStore
列,在DATA
中找到的内容也可能无法访问试图找到一条道路。另外,用户选择的ACTION_PICK
的实现可能始终不会返回MediaStore
Uri
。
如果您需要选择一个内容,保留其Uri
,然后使用该Uri
来处理内容,则需要:
-
使用
ACTION_OPEN_DOCUMENT
代替ACTION_PICK
-
在
takePersistableUriPermissions()
上致电ContentResolver
,传入您所获得的Uri
现在,您具有对内容的长期访问权限...假设用户没有进行诸如删除内容之类的戏剧性操作。 ?