如何使用带有最新 Android 存储框架的 Intent 操作打开文件?

how to open files using intent action with latest Android storage framework?

自从 Android 最近对存储框架进行了重大更改以来,许多文档都在讨论权限和范围存储。但是我找不到有关如何处理文件的 Uri 以使其被其他应用程序读取的详细信息。

其他应用对文件的 view/read 意图操作失败。我不明白这里有什么问题;

  1. java.io.Filejava.nio.File之间的difference有关系吗?
  2. Uri 缺少权限或 Uri 格式不正确。

Android storage samples (FileManager) has this bug as well. It lists all the files in a directory successfully but can't open a selected image, or a document. I've reported this issue 但目前没有任何帮助。

以下片段来自 FileManager(存储样本)

fun openFile(activity: AppCompatActivity, selectedItem: File) {
    // Get URI and MIME type of file
    val uri = Uri.fromFile(selectedItem).normalizeScheme()
    val mime: String = getMimeType(uri.toString())

    // Open file with user selected app
    val intent = Intent()
    intent.action = Intent.ACTION_VIEW
    intent.data = uri
    intent.type = mime
    return activity.startActivity(intent)
}

经过评论的提示,我在developer docs中找到了答案。

Caution: If you want to set both the URI and MIME type, don't call setData() and setType() because they each nullify the value of the other. Always use setDataAndType() to set both URI and MIME type.

openFile没有在android-storage-samples中抛出FileUriExposedException的原因是设置intent.type,Uri 被取消,当我将其更改为 setDataAndType() 时,我得到了异常。最后的片段看起来像

fun openFile(activity: AppCompatActivity, selectedItem: File) {
// Get URI and MIME type of file
val uri = FileProvider.getUriForFile(activity.applicationContext, AUTHORITY, selectedItem)
//    val uri = Uri.fromFile(selectedItem).normalizeScheme()
val mime: String = getMimeType(uri.toString())

// Open file with user selected app
    val intent = Intent()
    intent.action = Intent.ACTION_VIEW
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
//    intent.data = uri
//    intent.type = mime
    intent.setDataAndType(uri, mime)
    return activity.startActivity(intent)
}

我认为他们忘记随着时间的推移更新示例,让我创建一个拉取请求以在那里也提交此更改。