如何使用 URI 通过 Intent 在另一个应用程序中打开文件?

How to open a file in another app via an Intent using an URI?

在我的应用程序中,我有几个文件 Uri(不是 URI)存储。它们的形式是:

content://com.android.providers.downloads.documents/document/427

我的意图是,单击一个按钮后,在文件 reader 中打开这些 Uri 之一(可能是 MS Word、Excel、PDF Reader...取决于扩展程序和设备)。

我目前正在尝试这个片段:

                val file = File(Uri.parse(uri).path!!)
                val myMime: MimeTypeMap = MimeTypeMap.getSingleton()
                val newIntent = Intent(Intent.ACTION_VIEW)

                val mimeType: String = myMime.getMimeTypeFromExtension(file.extension).toString()
                newIntent.setDataAndType(
                    FileProvider.getUriForFile(applicationContext, "${applicationContext.packageName}.provider", file), mimeType)
                newIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
                newIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
                try {
                    startActivity(newIntent)
                } catch (e: ActivityNotFoundException) {
                }

但每次我尝试打开它时,我都会得到:

java.lang.IllegalArgumentException: Failed to find configured root that contains /document/427

你能告诉我我错过了什么吗?我在这里找不到针对我的问题的答案。提前致谢!

更新 感谢@CommonsWare 的帮助,我设法避免了异常,我的代码现在看起来像这样:

val newIntent = Intent(Intent.ACTION_VIEW)
newIntent.addCategory(Intent.CATEGORY_OPENABLE)
newIntent.data = Uri.parse(uri)
newIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
newIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
try {
    startActivity(newIntent)
} catch (e: ActivityNotFoundException) {
    Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show()
}

我从这里获取 Uri:

val fileResultLauncher =      registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    viewModel.uploadFile(result, false)
            }

fileFab.setOnClickListener {
    val intent = Intent()
    intent.type = "application/*"
    intent.action = Intent.ACTION_OPEN_DOCUMENT
    fileResultLauncher.launch(intent)
}

不幸的是,我得到了 NoActivityFoundException

摆脱:

val file = File(Uri.parse(uri).path!!)

...并将您的 setDataAndType() 调用替换为:

newIntent.setDataAndType(Uri.parse(uri), mimeType)