gpt4 book ai didi

Android Kotlin : Getting a FileNotFoundException with filename chosen from file picker?

转载 作者:行者123 更新时间:2023-12-01 16:15:37 26 4
gpt4 key购买 nike

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

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

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=111, result=-1, data=Intent { dat=content://com.android.externalstorage.documents/document/0000-0000:Sudoku puzzles/hard001.txt flg=0x1 }} to activity {com.example.sudokusolver/com.example.sudokusolver.MainActivity}: java.io.FileNotFoundException: /document/0000-0000:Sudoku puzzles/hard001.txt (No such file or directory)

最佳答案

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

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)

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

关于Android Kotlin : Getting a FileNotFoundException with filename chosen from file picker?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62397183/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com