Bird
Raised Fist0
Android Kotlinmobile~20 mins

File access and storage in Android Kotlin - Mini App: Build & Ship

Choose your learning style10 modes available
Build: Simple File Storage
This screen lets the user write text to a file and read it back to display on screen.
Target UI
-------------------------
| Simple File Storage    |
|-----------------------|
| Enter text:           |
| [___________________] |
|                       |
| [Save]   [Load]       |
|                       |
| File content:         |
| ____________________  |
|                       |
-------------------------
A TextField for user to enter text
A Save button that writes the text to a file in internal storage
A Load button that reads the text from the file and shows it below
Show the loaded file content in a TextView
Handle exceptions gracefully with Toast messages
Starter Code
Android Kotlin
package com.example.filestorage

import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import java.io.File

class MainActivity : AppCompatActivity() {
    private lateinit var inputEditText: EditText
    private lateinit var saveButton: Button
    private lateinit var loadButton: Button
    private lateinit var contentTextView: TextView

    private val filename = "myfile.txt"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        inputEditText = findViewById(R.id.inputEditText)
        saveButton = findViewById(R.id.saveButton)
        loadButton = findViewById(R.id.loadButton)
        contentTextView = findViewById(R.id.contentTextView)

        // TODO: Add click listeners for saveButton and loadButton
    }
}
Task 1
Task 2
Task 3
Solution
Android Kotlin
package com.example.filestorage

import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import java.io.File
import java.io.IOException

class MainActivity : AppCompatActivity() {
    private lateinit var inputEditText: EditText
    private lateinit var saveButton: Button
    private lateinit var loadButton: Button
    private lateinit var contentTextView: TextView

    private val filename = "myfile.txt"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        inputEditText = findViewById(R.id.inputEditText)
        saveButton = findViewById(R.id.saveButton)
        loadButton = findViewById(R.id.loadButton)
        contentTextView = findViewById(R.id.contentTextView)

        saveButton.setOnClickListener {
            val textToSave = inputEditText.text.toString()
            try {
                openFileOutput(filename, MODE_PRIVATE).use { output ->
                    output.write(textToSave.toByteArray())
                }
                Toast.makeText(this, "File saved", Toast.LENGTH_SHORT).show()
                inputEditText.text.clear()
            } catch (e: IOException) {
                Toast.makeText(this, "Error saving file", Toast.LENGTH_SHORT).show()
            }
        }

        loadButton.setOnClickListener {
            try {
                val file = File(filesDir, filename)
                if (file.exists()) {
                    val content = file.readText()
                    contentTextView.text = content
                    Toast.makeText(this, "File loaded", Toast.LENGTH_SHORT).show()
                } else {
                    Toast.makeText(this, "File not found", Toast.LENGTH_SHORT).show()
                    contentTextView.text = ""
                }
            } catch (e: IOException) {
                Toast.makeText(this, "Error loading file", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

This app uses Android internal storage to save and load a simple text file named myfile.txt.

When the user taps Save, the app writes the text from the input field to the file using openFileOutput with MODE_PRIVATE, which means only this app can access the file.

When the user taps Load, the app checks if the file exists in the internal files directory, reads its content as text, and shows it in the TextView below.

Toast messages inform the user about success or errors during file operations.

This approach keeps file access simple and secure inside the app's private storage.

Final Result
Completed Screen
-------------------------
| Simple File Storage    |
|-----------------------|
| Enter text:           |
| [Hello world       ]  |
|                       |
| [Save]   [Load]       |
|                       |
| File content:         |
| Hello world           |
|                       |
-------------------------
User types text in the input field.
User taps Save: text is saved to internal file, input clears, Toast shows 'File saved'.
User taps Load: file content is read and displayed below, Toast shows 'File loaded'.
If file missing or error, Toast shows appropriate message.
Stretch Goal
Add a Clear button that deletes the saved file and clears the displayed content.
💡 Hint
Use File.delete() on the internal file and clear the TextView text.

Practice

(1/5)
1. Which method is used in Android Kotlin to write data to a private file within the app's internal storage?
easy
A. writeExternalStorage
B. openFileInput
C. readFile
D. openFileOutput

Solution

  1. Step 1: Understand file writing methods

    openFileOutput is the method designed to write data to a private file in internal storage.
  2. Step 2: Differentiate from reading methods

    openFileInput is used for reading, not writing files.
  3. Final Answer:

    openFileOutput -> Option D
  4. Quick Check:

    Write file = openFileOutput [OK]
Hint: Writing files uses openFileOutput, reading uses openFileInput [OK]
Common Mistakes:
  • Confusing openFileInput with writing method
  • Using external storage methods for internal files
  • Assuming readFile is a valid Android method
2. Which of the following is the correct Kotlin syntax to open a file named "data.txt" for reading in an Android app?
easy
A. val input = openFileOutput("data.txt", Context.MODE_PRIVATE)
B. val input = openFileInput("data.txt")
C. val input = openFile("data.txt", Context.MODE_PRIVATE)
D. val input = readFile("data.txt")

Solution

  1. Step 1: Identify the correct method for reading files

    openFileInput is the correct method to open a file for reading in Android Kotlin.
  2. Step 2: Check syntax correctness

    openFileInput takes only the filename as a parameter, no mode needed.
  3. Final Answer:

    val input = openFileInput("data.txt") -> Option B
  4. Quick Check:

    Read file = openFileInput(filename) [OK]
Hint: openFileInput(filename) opens file for reading [OK]
Common Mistakes:
  • Using openFileOutput for reading
  • Adding mode parameter to openFileInput
  • Using non-existent readFile method
3. What will be the output of the following Kotlin code snippet in an Android app?
val filename = "note.txt"
val fileContents = "Hello World"
openFileOutput(filename, Context.MODE_PRIVATE).use {
  it.write(fileContents.toByteArray())
}
val input = openFileInput(filename).bufferedReader().use { it.readText() }
println(input)
medium
A. note.txt
B. null
C. Hello World
D. FileNotFoundException

Solution

  1. Step 1: Write text to file

    The code writes "Hello World" to "note.txt" using openFileOutput.
  2. Step 2: Read text from the same file

    openFileInput reads the file content back as a string.
  3. Final Answer:

    Hello World -> Option C
  4. Quick Check:

    Write then read file = "Hello World" [OK]
Hint: Write then read file returns the original string [OK]
Common Mistakes:
  • Expecting filename instead of content
  • Assuming file is empty or null
  • Not closing streams causing errors
4. Consider this Kotlin code snippet in an Android app:
val input = openFileInput("config.txt")
val text = input.bufferedReader().readText()
input.close()
What is the main issue with this code?
medium
A. Not using 'use' block to safely close the stream
B. The input stream is closed before reading text
C. bufferedReader() cannot be called on input streams
D. openFileInput should be called with Context.MODE_PRIVATE

Solution

  1. Step 1: Check resource management

    The code manually closes the input stream but risks exceptions if readText() fails.
  2. Step 2: Use 'use' block for safety

    Using 'use' automatically closes the stream safely even if errors occur.
  3. Final Answer:

    Not using 'use' block to safely close the stream -> Option A
  4. Quick Check:

    Safe stream closing = use block [OK]
Hint: Always use 'use' to auto-close streams safely [OK]
Common Mistakes:
  • Adding mode parameter to openFileInput
  • Closing stream before reading
  • Believing bufferedReader() is invalid here
5. You want to save user preferences as a JSON string in a private file named "prefs.json" and then read it back safely. Which Kotlin code snippet correctly writes and reads this file in an Android app?
hard
A. openFileOutput("prefs.json", Context.MODE_PRIVATE).use { it.write(jsonString.toByteArray()) } val json = openFileInput("prefs.json").bufferedReader().use { it.readText() }
B. openFileInput("prefs.json").use { it.write(jsonString.toByteArray()) } val json = openFileOutput("prefs.json", Context.MODE_PRIVATE).bufferedReader().use { it.readText() }
C. val file = File("prefs.json") file.writeText(jsonString) val json = file.readText()
D. val fos = openFileOutput("prefs.json") fos.write(jsonString.toByteArray()) fos.close() val fis = openFileInput("prefs.json") val json = fis.bufferedReader().readText() fis.close()

Solution

  1. Step 1: Write file using openFileOutput with 'use'

    openFileOutput("prefs.json", Context.MODE_PRIVATE).use { it.write(jsonString.toByteArray()) } val json = openFileInput("prefs.json").bufferedReader().use { it.readText() } correctly writes the JSON string to "prefs.json" using openFileOutput and safely closes the stream with 'use'.
  2. Step 2: Read file using openFileInput with 'use'

    It then reads the file back safely using openFileInput and 'use' to auto-close the stream.
  3. Final Answer:

    openFileOutput("prefs.json", Context.MODE_PRIVATE).use { it.write(jsonString.toByteArray()) } val json = openFileInput("prefs.json").bufferedReader().use { it.readText() } -> Option A
  4. Quick Check:

    Write/read private file safely = openFileOutput/input + use [OK]
Hint: Use openFileOutput/input with 'use' to safely write/read files [OK]
Common Mistakes:
  • Mixing up openFileInput and openFileOutput
  • Using File class for internal storage without context
  • Not closing streams properly causing leaks
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard