- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一个 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/
我是一名优秀的程序员,十分优秀!