Internal and External Storage in Android Development
In Android development, storage is an essential part of saving and retrieving data. Android provides two main types of storage: Internal Storage and External Storage. Both have their own use cases and access restrictions. Let’s explore both options, and how to use them in Android with Kotlin.
1. Internal Storage
Internal Storage refers to the storage space on the device that is private to the application. Each app has its own private storage area on the device. Files stored in internal storage are private and cannot be accessed by other applications.
Writing to Internal Storage
To write to internal storage, you use the openFileOutput
method to open or create a file and then write data to it.
Example 1: Writing Data to a File in Internal Storage
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val filename = "myfile.txt" val fileContents = "This is a sample text saved in internal storage." // Writing to internal storage try { openFileOutput(filename, Context.MODE_PRIVATE).use { it.write(fileContents.toByteArray()) } Toast.makeText(this, "File saved to internal storage", Toast.LENGTH_SHORT).show() } catch (e: IOException) { e.printStackTrace() } } }
In this example:
openFileOutput(filename, Context.MODE_PRIVATE)
opens or creates a file in the internal storage. TheMODE_PRIVATE
flag ensures that the file is private to the app.it.write(fileContents.toByteArray())
writes the content into the file.
Reading from Internal Storage
To read from internal storage, you use the openFileInput
method.
Example 2: Reading Data from a File in Internal Storage
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val filename = "myfile.txt" // Reading from internal storage try { val fileInputStream = openFileInput(filename) val inputStreamReader = InputStreamReader(fileInputStream) val bufferedReader = BufferedReader(inputStreamReader) val fileContents = bufferedReader.readLine() Toast.makeText(this, "Read from file: $fileContents", Toast.LENGTH_LONG).show() } catch (e: FileNotFoundException) { e.printStackTrace() } } }
In this example:
openFileInput(filename)
opens the file in internal storage for reading.BufferedReader.readLine()
reads the file content line by line.
2. External Storage
External Storage refers to storage that is available to all apps on the device and can be accessed by the user. External storage includes both removable storage like SD cards and non-removable storage that is part of the device. Files stored in external storage are not private and can be accessed by other apps.
Note: Starting from Android 10 (API level 29), direct access to external storage is restricted for apps, and developers are encouraged to use Scoped Storage.
Writing to External Storage
Before writing to external storage, you need to request the necessary permissions. You can write to public directories (like pictures or downloads) using getExternalStoragePublicDirectory
.
Example 3: Writing Data to External Storage
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val filename = "example.txt" val fileContents = "This is a sample text saved in external storage." // Check if permission is granted if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), filename) try { file.writeText(fileContents) Toast.makeText(this, "File saved to external storage", Toast.LENGTH_SHORT).show() } catch (e: IOException) { e.printStackTrace() } } else { // Request permission ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1) } } }
In this example:
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
gets a public directory on the external storage to store the file.file.writeText(fileContents)
writes text content to the file.
Reading from External Storage
You can also read from external storage similarly using FileInputStream
.
Example 4: Reading Data from External Storage
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val filename = "example.txt" // Check if permission is granted if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), filename) try { val fileContents = file.readText() Toast.makeText(this, "Read from file: $fileContents", Toast.LENGTH_LONG).show() } catch (e: IOException) { e.printStackTrace() } } else { // Request permission ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 1) } } }
In this example:
file.readText()
reads the text content of the file stored on external storage.
3. Scoped Storage (Android 10 and Above)
For devices running Android 10 (API level 29) or higher, direct access to the entire external storage is restricted. Android encourages the use of Scoped Storage, which gives apps access to only their app-specific directories or media collections like photos, music, etc.
Example 5: Using Scoped Storage
val contentResolver: ContentResolver = applicationContext.contentResolver val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI val values = ContentValues() values.put(MediaStore.Images.Media.TITLE, "Sample Image") values.put(MediaStore.Images.Media.DESCRIPTION, "Sample Image Description") val imageUri: Uri? = contentResolver.insert(uri, values) Toast.makeText(this, "Scoped storage file saved", Toast.LENGTH_SHORT).show()
This example shows how to use the MediaStore to save files using scoped storage. Apps can access only specific directories (like images) and must request permission accordingly.
4. Conclusion
Both internal and external storage have their uses in Android development. Internal storage is perfect for app-specific data, while external storage can be used for sharing data with other apps. Starting with Android 10, it’s important to use Scoped Storage for better data security and app compatibility.