3

I am creating a simple Android app where when a user clicks on a button, a file picker appears in which a user selects a file, and the app reads the contents of the file. However, in my code below, I get a FileNotFound following error after selecting a file (at the line where the File object is instantiated):

EXCEPTION: java.io.FileNotFoundException: /document/6471 (No such file or directory)

Below is my code:

// File picker implementation
private fun chooseFile(view:View) {
    println("chooseFile activated!");
    var selectFile = Intent(Intent.ACTION_GET_CONTENT)
    selectFile.type = "*/*"
    selectFile = Intent.createChooser(selectFile, "Choose a file")
    startActivityForResult(selectFile, READ_IN_FILE)
}


/* After startActivityForResult is executed, when the selectFile Intent is completed, onActivityResult is executed with
   the result code READ_IN_FILE.*/
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)

    if (requestCode == READ_IN_FILE) { // Step 1: When a result has been received, check if it is the result for READ_IN_FILE
        if (resultCode == Activity.RESULT_OK) { // Step 2: Check if the operation to retrieve thea ctivity's result is successful
            // Attempt to retrieve the file
            try {
                // Retrieve the true file path of the file
                var uri: Uri? = data?.getData();
                // Instantiate a File object from the file name
                var file:File = File(uri?.getPath());

                // Read the file, line by line
                file.forEachLine { println(it) }
            } catch (e: Exception) { // If the app failed to attempt to retrieve the error file, throw an error alert
                println("EXCEPTION: " + e.toString());
                Toast.makeText(this, "Sorry, but there was an error reading in the file", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    var file1:Button = findViewById(R.id.file1);
    file1.setOnClickListener(::chooseFile)
}

Below is my XML code (activity_main.xml):

<Button
    android:id="@+id/file1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:fontFamily="sans-serif"
    android:text="File 1"
    android:textAllCaps="false"
    android:textSize="16sp" />
4
  • Can you please share your log? Commented Dec 26, 2019 at 16:42
  • 2
    Of course you get a file not found exception as .getPath() does not give you a path to a file as you can see. Use .toString() to get the content scheme. You are number 53 who does this wrong this week so reading some pages tagged android could help you already. Commented Dec 26, 2019 at 18:13
  • You need to resolve the URI from the content resolver to get the actual path. Do you need to support only text files or any mime media type like images, audio, video? Commented Dec 27, 2019 at 6:51
  • @VaikundamRaghul I only need to read text files (txt, word, pdf, etc.) Commented Dec 27, 2019 at 7:21

1 Answer 1

2
// File picker implementation
private fun chooseFile(view:View) {
    //only the below specified mime type is allowed in the picker
    val mimeTypes = arrayOf(
        "application/msword",
        "application/vnd.ms-powerpoint",
        "application/vnd.ms-excel",
        "text/plain",
        "application/pdf"
    )
    println("chooseFile activated!");
    var selectFile = Intent(Intent.ACTION_GET_CONTENT)
    selectFile.type = if (mimeTypes.size == 1) mimeTypes[0] else "*/*"
        if (mimeTypes.isNotEmpty()) {
            selectFile.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
        }
    selectFile = Intent.createChooser(selectFile, "Choose a file")
    startActivityForResult(selectFile, READ_IN_FILE)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == 200) { // Step 1: When a result has been received, check if it is the result for READ_IN_FILE
        if (resultCode == Activity.RESULT_OK) { // Step 2: Check if the operation to retrieve thea ctivity's result is successful
            // Attempt to retrieve the file
            try {
                data?.data?.let {
                    contentResolver.openInputStream(it)
                }?.let {
                    val r = BufferedReader(InputStreamReader(it))
                    while (true) {
                        val line: String? = r.readLine() ?: break
                        println(line)
                    }
                }

            } catch (e: Exception) { // If the app failed to attempt to retrieve the error file, throw an error alert
                Toast.makeText(
                    this,
                    "Sorry, but there was an error reading in the file",
                    Toast.LENGTH_SHORT
                ).show()
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.