且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-05-18 08:28:59

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

You did not receive a file path, you received a Uri. You have to use Uri based APIs such as ContentResolver.openInputStream() to access the contents at that Uri as Android does not grant your app direct File access to the underlying file (it could also be streamed from Google Drive or downloaded directly from the internet without your app being aware that this is happening):

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 扩展名作为一部分其路径):

Here we can assume we get contents of the proper format by passing in the proper mime type to our request (as there is no requirement that a text file end in exactly the .txt extension as part of its path):

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

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

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

Which will automatically make any non text file unable to be selected.