如何正确授予权限以打开通过 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 实例,而不是其他活动或未来的应用进程。