【问题标题】:How to open a file in another app via an Intent using an URI?如何使用 URI 通过 Intent 在另一个应用程序中打开文件?
【发布时间】:2022-02-14 21:00:34
【问题描述】:

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

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

我的意图是,一旦我单击一个按钮,在文件阅读器中打开其中一个 Uri(可能是 MS Word、Excel、PDF 阅读器......取决于扩展名和设备)。

我目前正在尝试这个 sn-p:

                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

【问题讨论】:

  • 尝试自己打开并阅读 uri,然后再尝试让其他应用执行此操作。我敢打赌,您的应用程序已经不允许打开它。使用 getContentResolver().openInputStream(uri) 然后从流中读取。
  • 它是文档(docx、xlsx、pdf...)文件的 uri。我真的不能不使用另一个应用程序来打开它。
  • ????你说的根本没有意义。您要求使用另一个应用程序:How to open a file in another app via an Intent using an URI?

标签: android file kotlin filesystems document


【解决方案1】:

摆脱:

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

...并将您的 setDataAndType() 电话替换为:

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

【讨论】:

  • 但是如果我没有文件,val mimeType: String = myMime.getMimeTypeFromExtension(file.extension).toString() 呢?
  • @xvlaze:您可以只使用setData()(或在Intent 构造函数中提供Uri)。 content Uri 的文档提供程序将向 Android 报告它的 MIME 类型是什么。您不必自己提供 MIME 类型。
  • 已尝试setData()`` and saw some improvement. Thanks in advance! Now I'm getting: SecurityException:UID 10262 没有对 content://(...) 的权限,您可以使用 OPEN_DOCUMENT 或相关 API 获得访问权限```。所以我将 Intent 类型更改为 Intent(Intent.ACTION_OPEN_DOCUMENT) 但现在我得到了一个文件选择器而不是“打开方式...”消歧对话框。
  • @xvlaze:如果您想保持Uri 值,ACTION_OPEN_DOCUMENTtakePersistableUriPermission() 是您长期访问内容的唯一选择。如果您只是想在活动之间传递Uri,要么摆脱活动(并使用多个片段或可组合),要么使用setData()FLAG_GRANT_READ_URI_PERMISSION 在活动之间传递Uri。请参阅this blog post 了解更多信息。
  • @xvlaze:不一定有一个应用程序可以查看所有可能的 MIME 类型。不过,我会删除 newIntent.addCategory(Intent.CATEGORY_OPENABLE) 看看是否有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多