filedirectorycrashandroid-jetpack-composestorage

App Crashes Whenever Trying To Read File Saved Into Internal Storage In Android application


I'm trying to create a simple android application where value from a text field is saved into a file and is then later displayed on screen in a text composable on a button press, however the application crashes whenever I try to read the file.

I created a directory called "noteDirectory". It holds one file called "note". Here is the code

`// Directory That Holds Notes
val noteDirectory = File(applicationContext.filesDir, "notes")
noteDirectory.mkdir()
        
// File That Holds Note
val note = File(noteDirectory, "note.txt")`

Here is the business logic for the application. There is a string value that holds the value for the text field called "createNoteTextValue". There is another string value that holds the value for the text composable that displays the saved file. Finally there is a function called "saveValue" that saves the value from "createNoteTextValue" into the "note' file.

`// Value For TextField That Is Saved Into File
var createNoteTextValue by remember { mutableStateOf("") }

// Value For Text That Displays Saved Note
var displayNoteTextValue by remember { mutableStateOf("") }

// Function That Saves Note
fun saveValue() {
    applicationContext.openFileOutput("note.txt", Context.MODE_PRIVATE).use {
      it.write(createNoteTextValue.toByteArray())
    }
}`

Here is the UI. There is a column that takes up the entire screen. Inside of the column is a text field, two buttons, and a text composable. The text field holds the value that will be stored into the file. The first button calls the "saveValue" function. The second button is supposed to display the saved file into the text composable, however it doesn't.

`// Application Layout
Column(
  horizontalAlignment = Alignment.CenterHorizontally,
  verticalArrangement = Arrangement.Center,
  modifier = Modifier
     .fillMaxSize()
) {

   // TextField That Holds Note
   TextField(value = createNoteTextValue, onValueChange = {createNoteTextValue = it})

   // Button That Saves Note
   Button(onClick = { saveValue() }) {
     Text(text = "Save")
   }

   // Button That Displays Saved Note
   Button(onClick = { displayNoteTextValue = note.readText() }) {
      Text(text = "Show")
    }

    // Text That Displays Saved Note
    Text(text = displayNoteTextValue)
 }`
        

And this is all placed inside of the main activity.

Where I try to read the value of the "note" file, the application crashes. I have pinpointed the problem but I don't know how to fix it. Is has something to do with the directory. Whenever I remove the directory and place the "applicationContext.fileDir" into the parent parameter in the "note" file, it works.


Solution

  • The problem is that your openFileOutput() is writing the note.txt file to the / directory and not to notes/ directory. So the file is not available for reading under notes/note.txt, causing the application to crash.

    Unfortunately, you can't use openFileOutput() with a file path. So instead, you can use the writeText() function like this:

    note.writeText(createNoteTextValue)
    

    Note that you can inspect the data directory of your app by using the Device Explorer View in Android Studio:

    enter image description here

    When we inspect it after running our code, we can see that the empty notes directory is created, but the file with the contents is created next to it instead of inside it:

    enter image description here

    The path to the data directory of your app is

    /data/user/0/my.demo.project/files/

    Also, the Logcat View in Android Studio could have given you a hint what the problem is:

    FATAL EXCEPTION: main                                                                                               
    Process: my.demo.project, PID: 31714                                                                                              
    java.io.FileNotFoundException: /data/user/0/my.demo.project/files/notes/note.txt: open failed: ENOENT (No such file or directory)