如何正确授予权限以打开通过 OpenDocument() 获取的文件?
How do I grant permission correctly to open files obtained through OpenDocument()?
我正在制作一个应用程序,您可以在其中 select 存储中的图像或文档,然后将它们显示在类似于 Google Drive 的列表中,因此您可以选择一个并打开你可以查看它。这个列表是使用 RecyclerView 实现的,我将 uri 和文件类型存储在 SharedPreferences 的 json 中。我使用以下方法获取内容:
val getFile = registerForActivityResult(
ActivityResultContracts.GetContent()
) {
if (it != null) {
val fileLink = FileLink()
fileLink.setUri(it.toString())
fileLink.setType(contentResolver.getType(it)!!)
fileLink.setName(getFileName(it)!!)
list.add(fileLink)
presenter.saveChangesToList(list)
adapter.notifyDataSetChanged()
}
}
然后我就打电话给:
getFile.launch("image/*|application/pdf")
这并没有让我从内部存储中挑选东西(文件显示为灰色)并且它实际上并没有过滤 select 可用的文件。不过,它与用相机拍摄的图像完美搭配。
为了解决“无法从存储中挑选东西”的问题,我将 GetContent() 更改为 OpenDocument():
val getFile = registerForActivityResult(
ActivityResultContracts.OpenDocument()
) {
if (it != null) {
val fileLink = FileLink()
fileLink.setUri(it.toString())
fileLink.setType(contentResolver.getType(it)!!)
fileLink.setName(getFileName(it)!!)
list.add(fileLink)
presenter.saveChangesToList(list)
adapter.notifyDataSetChanged()
}
}
然后我打电话给:
getFile.launch(
arrayOf(
"application/pdf",
"image/*"
)
)
有了这个,我可以从存储中 select 文件,它还允许我限制,所以你只能选择图像或 pdf。我现在的问题是,如果我得到这样的东西,我可以打开文档一次。如果我关闭我的应用程序并再次打开它并尝试再次打开文档,我会收到此错误:
java.lang.SecurityException: UID 10156 does not have permission to content://com.android.providers.downloads.documents/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2FNewPdf
我使用以下代码打开文档:
viewHolder.itemView.setOnClickListener {
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(
Uri.parse(fileList[position].getUri().toString()),
fileList[position].getType()
)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
context.startActivity(intent)
}
我能得到一些帮助吗?我猜这与读取 uris 的权限有关,但我不知道如何修复它。我也不明白为什么我第一次可以正确打开文件,但重启后就不行了。
您没有在 ContentResolver
上将 Uri
交给所选内容后立即调用 takePersistableUriPermission()
。
因此,your rights to access the content will expire — 您访问内容的权利将仅限于收到 Uri
的一个 activity 实例,而不是其他活动或未来的应用进程。
我正在制作一个应用程序,您可以在其中 select 存储中的图像或文档,然后将它们显示在类似于 Google Drive 的列表中,因此您可以选择一个并打开你可以查看它。这个列表是使用 RecyclerView 实现的,我将 uri 和文件类型存储在 SharedPreferences 的 json 中。我使用以下方法获取内容:
val getFile = registerForActivityResult(
ActivityResultContracts.GetContent()
) {
if (it != null) {
val fileLink = FileLink()
fileLink.setUri(it.toString())
fileLink.setType(contentResolver.getType(it)!!)
fileLink.setName(getFileName(it)!!)
list.add(fileLink)
presenter.saveChangesToList(list)
adapter.notifyDataSetChanged()
}
}
然后我就打电话给:
getFile.launch("image/*|application/pdf")
这并没有让我从内部存储中挑选东西(文件显示为灰色)并且它实际上并没有过滤 select 可用的文件。不过,它与用相机拍摄的图像完美搭配。 为了解决“无法从存储中挑选东西”的问题,我将 GetContent() 更改为 OpenDocument():
val getFile = registerForActivityResult(
ActivityResultContracts.OpenDocument()
) {
if (it != null) {
val fileLink = FileLink()
fileLink.setUri(it.toString())
fileLink.setType(contentResolver.getType(it)!!)
fileLink.setName(getFileName(it)!!)
list.add(fileLink)
presenter.saveChangesToList(list)
adapter.notifyDataSetChanged()
}
}
然后我打电话给:
getFile.launch(
arrayOf(
"application/pdf",
"image/*"
)
)
有了这个,我可以从存储中 select 文件,它还允许我限制,所以你只能选择图像或 pdf。我现在的问题是,如果我得到这样的东西,我可以打开文档一次。如果我关闭我的应用程序并再次打开它并尝试再次打开文档,我会收到此错误:
java.lang.SecurityException: UID 10156 does not have permission to content://com.android.providers.downloads.documents/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2FNewPdf
我使用以下代码打开文档:
viewHolder.itemView.setOnClickListener {
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(
Uri.parse(fileList[position].getUri().toString()),
fileList[position].getType()
)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
context.startActivity(intent)
}
我能得到一些帮助吗?我猜这与读取 uris 的权限有关,但我不知道如何修复它。我也不明白为什么我第一次可以正确打开文件,但重启后就不行了。
您没有在 ContentResolver
上将 Uri
交给所选内容后立即调用 takePersistableUriPermission()
。
因此,your rights to access the content will expire — 您访问内容的权利将仅限于收到 Uri
的一个 activity 实例,而不是其他活动或未来的应用进程。