微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用系统对话框打开任何文件类型进行查看

如何解决使用系统对话框打开任何文件类型进行查看

在我的应用程序中,我希望用户能够选择他们想要的任何文件(.mp4、.pdf 等),在应用程序中显示文件名和扩展名,最后允许他们打开引用的文件使用系统对话框。我已经成功打开文件选择器对话框,获取所选文件的路径和信息,但我无法理解如何使用该文件的路径来触发将处理文件打开过程的操作系统对话框。我已经阅读了一些关于 SAF 和 ACTION_OPEN_DOCUMENT 操作的内容,但我似乎无法理解是否有必要或者如何去做。

这是我的文件检索过程:

private fun openFilePicker() { 
   val intent = Intent(Intent.ACTION_GET_CONTENT)
   intent.type = "*/*"
   startActivityForResult(intent,PICKFILE_RESULT_CODE)
}

override fun onActivityResult(requestCode: Int,resultCode: Int,data: Intent?) {
        when (requestCode) {
            PICKFILE_RESULT_CODE -> if (resultCode == RESULT_OK) {
                val filePath: String? = data?.data?.path
                if (filePath != null) attachmentsAdapter.addFilePath(filePath) else Toast.makeText(
                    requireContext(),"Something went wrong,please try again!",Toast.LENGTH_SHORT
                ).show()
            }
            else -> super.onActivityResult(requestCode,resultCode,data)
        }
    }

我知道引入 SAF 是为了改善用户的隐私,并且应用程序最初只能访问他们自己的目录(以及我认为的一些公共目录),但是我真的需要做一些诸如创建自己的目录、复制在那里引用文件,然后做任何我需要做的事情来打开它们?

根据 CommonsWare 的回答进行更新

正如 CommonsWare 所说,诀窍是简单地避免使用返回的 URI 的路径,而是使用 URI 本身。有关详细信息,请参阅他们的回答。

此外,由于我只使用文件的 URI,因此获取名称和扩展名有点不同。以下是使用 Cursor 的方法

private fun getFileNameWithExtensionFromUri(currentFileUri: String): String? {
    val returnCursor: Cursor? = context.contentResolver.query(Uri.parse(currentFileUri),null,null)
    /*
     * Get the column indexes of the data in the Cursor,* move to the first row in the Cursor,get the data,* and display it.
     */
    val nameIndex = returnCursor?.getColumnIndex(OpenableColumns.disPLAY_NAME)
    returnCursor?.movetoFirst()
    val fileName = returnCursor?.getString(nameIndex!!)
    returnCursor?.close()
    return fileName
}

解决方法

这是我的文件检索过程

A Uri is not a filedata?.data?.path 通常不会返回文件系统路径。

我无法理解如何使用该文件的路径来触发将处理文件打开过程的操作系统对话框

Android 没有“将处理文件打开过程的操作系统对话框”,至少我会使用这些术语。

如果您想尝试打开某个可以查看内容的应用,请创建一个 ACTION_VIEW Intent

override fun onActivityResult(requestCode: Int,resultCode: Int,data: Intent?) {
        when (requestCode) {
            PICKFILE_RESULT_CODE -> if (resultCode == RESULT_OK) {
                data?.data?.let { uri ->
                  try {
                    startActivity(Intent(Intent.ACTION_VIEW,uri)).addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                  } catch (e: Exception) {
                    Toast.makeText(
                      requireContext(),"Something went wrong,please try again!",Toast.LENGTH_SHORT
                    ).show()
                  }
                }
            }
            else -> super.onActivityResult(requestCode,resultCode,data)
        }
    }

try/catch 很重要,因为您允许用户选择任何类型的内容,并且可能没有安装支持查看特定类型内容的应用。

,

您至少需要设置文件路径和正确的 MIME 类型。

val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension("pdf")
intent.setDataAndType(Uri.parse("file://$filePath"),mime)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。