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

问题描述 投票:0回答:1

我正在使用一个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()
        }
    }
}

FileNotFound异常在创建File对象以执行forEachLine循环的行上引发:

java.lang.RuntimeException:无法交付结果ResultInfo {who = null,request = 111,result = -1,data = Intent {dat = content://com.android.externalstorage.documents/document/0000-0000: Sudoku puzzles / hard001.txt flg = 0x1}}到活动{com.example.sudokusolver / com.example.sudokusolver.MainActivity}:java.io.FileNotFoundException:/ document / 0000-0000:Sudoku puzzles / hard001.txt(否这样的文件或目录)

android file exception kotlin filenotfoundexception
1个回答
0
投票

您未收到文件路径,但收到了Uri。您必须使用基于Uri的API,例如ContentResolver.openInputStream()来访问该ContentResolver.openInputStream()处的内容,因为Android并未授予您的应用直接Uri对基础文件的访问权限(也可以从Google云端硬盘中流式传输或下载)直接从互联网上获取,而您的应用程序不知道这种情况正在发生):

File

在这里,我们可以假定我们通过将正确的mime类型传递给我们的请求来获得正确格式的内容(因为不要求文本文件以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() } } } 扩展名作为其路径的一部分结尾):

.txt

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

© www.soinside.com 2019 - 2024. All rights reserved.