当前位置: 首页 > 知识库问答 >
问题:

Android Kotlin:获得从文件选择器中选择文件名的FileNotFoundException?

隆飞宇
2023-03-14

我正在开发一个Android应用程序,其中一个功能是让用户选择要打开的文件(我想打开一个纯文本的.txt文件)。我以前用Java开发过Android应用程序,但这次我使用的是Kotlin,而且这是我第一次使用Kotlin。

我现在让应用程序显示一个文件选择器,让用户点击他们想要打开的文件。然后我尝试使用File对象打开文件并执行forEachLine循环。但是由于某种原因,它抛出了一个java.io.FileNotFoundException(没有这样的文件或目录),其中包含了从文件选择器中选择的文件。我不确定有什么问题,如果我必须做一些转换来转换文件路径?

“加载”按钮的代码:

val btn_load: Button = findViewById<Button>(R.id.btn_load_puzzle)
    btn_load.setOnClickListener {
        val intent = Intent()
            .setType("*/*")
            .setAction(Intent.ACTION_GET_CONTENT)

        startActivityForResult(Intent.createChooser(intent, "Select a file"), 111)
    }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)

    // Selected a file to load
    if ((requestCode == 111) && (resultCode == RESULT_OK)) {
        val selectedFilename = data?.data //The uri with the location of the file
        if (selectedFilename != null) {
            val filenameURIStr = selectedFilename.toString()
            if (filenameURIStr.endsWith(".txt", true)) {
                val msg = "Chosen file: " + filenameURIStr
                val toast = Toast.makeText(applicationContext, msg, Toast.LENGTH_SHORT)
                toast.show()
                File(selectedFilename.getPath()).forEachLine {
                    val toast = Toast.makeText(applicationContext, it, Toast.LENGTH_SHORT)
                    toast.show()
                }
            }
            else {
                val msg = "The chosen file is not a .txt file!"
                val toast = Toast.makeText(applicationContext, msg, Toast.LENGTH_LONG)
                toast.show()
            }
        }
        else {
            val msg = "Null filename data received!"
            val toast = Toast.makeText(applicationContext, msg, Toast.LENGTH_LONG)
            toast.show()
        }
    }
}

共有1个答案

苏鸿卓
2023-03-14

您没有收到文件路径,而是收到了URI。您必须使用基于URI的API(如ContentResolver.OpenInputStream())来访问该URI的内容,因为Android不授予应用程序直接file对底层文件的访问权限(它也可以从Google Drive流式传输或直接从internet下载,而应用程序没有意识到这一点):

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)

    // Selected a file to load
    if ((requestCode == 111) && (resultCode == RESULT_OK)) {
        val selectedFilename = data?.data //The uri with the location of the file
        if (selectedFilename != null) {
            contentResolver.openInputStream(selectedFilename)?.bufferedReader()?.forEachLine {
                val toast = Toast.makeText(applicationContext, it, Toast.LENGTH_SHORT)
                toast.show()
            }
        } else {
            val msg = "Null filename data received!"
            val toast = Toast.makeText(applicationContext, msg, Toast.LENGTH_LONG)
            toast.show()
        }
    }
}

在这里,我们可以假设通过向请求传递适当的mime类型来获得适当格式的内容(因为不要求文本文件以.txt扩展名作为其路径的一部分来结束):

val intent = Intent()
    .setType("text/*")
    .setAction(Intent.ACTION_GET_CONTENT)

startActivityForResult(Intent.createChooser(intent, "Select a file"), 111)

这将自动使任何非文本文件无法选择。

 类似资料:
  • 点击“添加文件”或“添加 URL”来添加导入源文件。然后,为源文件选择“编码”。 【注意】你可以同时导入多个文件。 ODBC 设置一个 ODBC 数据源连接 安装合适的 ODBC 管理员和文件相关的驱动程序。 在应用程序,选择“工具程式”->“ODBC 管理员”;或在 Navicat 中,在这个步骤点击“ODBC 管理员”按钮。 在“用户数据源名”选项卡点击“添加”按钮。 选择合适的 ODBC 驱

  • 主要内容:打开文件,扩展过滤器,保存文件,示例允许用户导航文件系统并选择一个文件或文件夹。 类位于包中。 打开文件 文件选择器可用作打开文件对话框,用于选择单个文件或多个文件,或作为文件保存对话框。以下代码创建一个对象并设置其标题,然后显示给用户。 可以通过设置和属性来配置文件选择器对话框窗口。 扩展过滤器 可以设置扩展过滤器来确定在文件选择器中打开哪些文件。 保存文件 FileChooser API允许用户为由应用程序保存的文件指定文件名及

  • 设置源文件的名。“导入从”文本框内的扩展名会根据在第一步已选择的导入类型而改变。然后,为源文件选择“编码”。 【注意】你可以同时导入多个文件。 Excel 工作表将会显示在“表”列表中。 Access 如果你的 Access 文件设有安全性设置(即表密码和用户安全性等级),你则需要输入所需的信息。点击“安全性”按钮来输入更多设置: 系统数据库文件 设置 Access 文件的系统安全性文件,例如:D

  • 设置源文件的名。“导入从”文本框内的扩展名会根据在第一步已选择的导入类型而改变。然后,为源文件选择“编码”。 【注意】你可以同时导入多个文件。 Excel 工作表将会显示在“表”列表中。 ODBC 设置一个 ODBC 数据源连接 若要设置数据源的连接,你要安装相关的驱动程序。 然后,将 DSN(数据源名)添加到 odbc.ini 配置文件中,例如 /etc/odbc.ini。 【注意】你可以向驱动

  • 我希望用户能够上传pdf和图像文件到服务器,并在选择文件后,我希望显示文件的名称和类型是.pdf还是.png 但文件扩展名不包括在文件路径中 这就是我的出发点 下面是我返回数据的方法 我尝试选择一个图像,但路径的值低于

  • 在尝试从android文件系统中选择图像时,我目前使用以下代码: 然后是一种方法,例如: 这是可行的,但实际上不允许我一次选择多个文件,也不允许我在默认照片库之外抓取照片。我尝试了一些我见过的其他建议,但没有任何效果。