Android Development — Working with Internal Storage and External Storage.
![](https://miro.medium.com/v2/resize:fit:700/1*mU23G_C9PPfPbOOwXRDRXQ.png)
“When someone discovers that you are writing a textbook, one question will be asked. “Why are you writing a book?” and the question is fairly easy to answer. You are writing a book because you are not entirely satisfied with the available texts.” — George Casella
This article is not a book, however it’s existence is justified by similar circumstances.
The official Android documentation carries no pages dedicated specifically to the topics of Internal and External storage. Though one of it’s pages provides an Overview of the Android Storage Model and explains the different ways you can store your application’s data, it still fails to provide any exact definitions of Internal or External storage and touches upon these topics only very briefly. This might leave new developers confused and wondering about the exact nature of these two storage entities.
The scope of this article is limited to developing a perspective about Internal and External storage and demonstrating a few techniques for interacting with them via code snippets.
Hold on, are you a student? Are you tired of using a notebook to keep track of your classes and deadlines? Worry not! Try ClassroomAid, I’ve built this app specifically for you and it’s a one stop solution for managing all your classroom related activities!
![](https://miro.medium.com/v2/resize:fit:72/1*MlUjYBqM1XjmnW1jLBe9ZQ.png)
Overview
The Android Storage Model is confusing. There is nothing simple or straight forward about it, especially if you are new to application development and the only experience that you possess with files and file systems comes from working with simple APIs provided by your programming language of choice.
However, the storage model on Android wasn’t always this complex. Back in the ancient days Android applications could do whatever they wanted, they could access external storage freely without having to ask for read or write permissions. But over the years, as user privacy has become a concern, the model has evolved in complexity.
First things first, what is External Storage? And how is it different from Internal storage? Strictly from the point of view of a developer, trying to find the exact locations of Internal or External storage on your device’s disk is an exercise in futility, because as a developer you do not need hard coded paths (e.g /sdcard or /data ) to their locations in order to be able to use them. I understand that as learners we are all obsessed with definitions, but unfortunately I would like to take this moment to disappoint you with some facts. The official Android documentation on storage, provides no clarification about the term ‘Internal storage’ and it only references external storage when talking about removable volumes as being a part of it. However, if you read the ‘Note’ provided on the documentation of this now deprecated method getExternalStorageDirectory(), you might begin to gain some idea about external storage.
Definitions
For the purpose of being able to work with Internal and External storage on Android, I consider the following superficial definitions sufficient:
Internal Storage: Internal storage is a closed non-shareable space which is always available on your device. It holds dedicated directories for each application which can be used by the applications to store sensitive and relevant data.
Thus, these dedicated directories are only accessible to their owner applications and are completely inaccessible to users or foreign applications. Also, because each of these directories are associated with an application, if the user uninstalls an application, it’s dedicated directory along with all it’s contents are removed from the device.
Note: On rooted devices, these directories are accessible to the user, so they aren’t completely secure. So avoid storing user/database passwords on XML files here.
External Storage: External storage is an open shared space which might not always be available on your device. It holds data that is shared among and is accessible to, all applications on the device. It is composed of the space provided by the device’s built-in shared storage along with the space provided by any mounted removable volumes (such as an SD card).
On some devices, there is no built-in external storage and thus external storage is provided by a mounted removable volume. In such a scenario, if the user unmounts the removable volume, the external storage is no longer available. Therefore it is an unreliable storage space which is not always guaranteed to be available unlike internal storage.
Keep in mind that the definitions provided above are not complete, they are only meant to provide a perspective for working with External and Internal storage.
If you really wish to be Alice in Wonderland and are ready to dive down the rabbit hole in search of the locations of Internal and External Storage on your device, then I would suggest you to curb your curiosity if you aren’t aware of what emulated file systems are, because diving down this rabbit hole could lead to a lot of confusion and could distort the view that the above two definitions have attempted to create. One reason for this? As this article points out, the location of external storage has changed over the years and continues to change over different devices. But if you continue to insist, I would point you to two more places besides that article:
https://developer.android.com/studio/debug/device-file-explorer
External Storage
The Past
Before Android O (API 29), the method getExternalStorageDirectory() was not deprecated and life was easier, most developers simply defined external storage as the directory tree returned by this method. Hence all you had to do to create a file on external storage was open a Byte Stream/Character Stream to the location returned by this method and write your bytes/characters to it just as you do when creating a file with Java (Although this was discouraged as it polluted the user’s root namespace and instead you were advised to write to a directory such as ‘Downloads’ under this directory tree using getExternalStoragePublicDirectory() method). Before Android KitKat (4.4) you only needed permission to write to this path, however after KitKat you also needed permission to read from this path. These permissions had to be explicitly granted by the user. Regardless, life was still a lot easier.
Below is an example code that I once used for creating a file under the ‘Downloads’ directory on external storage, this would still work on devices running versions of Android below Android O.
The Present
If you’ve taken the time to click on the documentation for the getExternalStorageDirectory() method, you are aware of the fact that beyond Android O, direct access to external storage is no longer supported and the path returned by this method is no longer accessible.
So how are we supposed to interact with external storage now?
The answer is: Use a Content Provider.
A content provider manages access to a shared repository of data. External storage is a shared repository of data. Hence it is natural that access to it is now managed by a content provider. But here’s another catch, depending on the type of data present in external storage we have two different content providers managing access:
- Media Provider: Manages access to shareable media files such as audio, video and image files.
- Documents Provider: Manages access to other types of shareable file as PDF files or EUPB format files.
These providers work under different frameworks, the Documents Provider is part of the Storage Access Framework and the Media Provider communicates through the MediaStore API. You can use a ContentResolver object to communicate with the MediaStore abstraction, however for communicating with a Documents Provider you need to follow the steps mentioned here and issue an Intent that contains a storage related intent action. There are three use cases under the Storage Access Framework and each action corresponds to one of those use cases.
Below is an example showing you how to create a file using the Documents Provider. When you issue an Intent with an action ‘ACTION_CREATE_DOCUMENT’ the Documents Provider shows a standard UI to the user, allowing them to navigate to a location on external storage and return a URI to that location. Then you can use the URI to open an OutputStream to the location and write to that location.
A Word on Permissions
You might have noticed that I have not talked about any permissions for writing to external storage using the Storage Access Framework, and the reason is that you do not need any! Because the Documents Provider provides a standard UI that is controlled by the user, permissions are automatically granted. When the user selects a file using the UI, the system issues a temporary URI permission grant to the application which allows the application to perform read/write operations on the file behind the URI.
With the MediaStore however, the situation is a bit different. You need to request permissions for reading and writing if your device runs Android 9 or below. However, with Android 10 and above, whether permissions need to be requested depends on whether your application uses scoped storage.
I know this is getting complicated, so I will not dwell on this anymore. You should watch this video on scoped storage for better a understanding.
Internal Storage
Frankly, with regards to Internal storage, nothing has changed and they continue to be a lot more easier to use than External storage. In order to access your application’s dedicated directories on Internal storage, all you need to do is use the methods:
getFilesDir() and getCacheDir()
These methods return the absolute paths to your application’s dedicated directories which you can then use to open an OutputStream or InputStream. From this point on, everything is same as working with files in Java.
For writing/reading to/from Internal storage, no permissions are required. However, keep in mind that the files you save to Internal storage though secure and inaccessible to other applications, are removed as soon as the user uninstalls your application.
Dedicated Directories on External Storage
This might sound a bit confusing, but there are also dedicated directories for your applications on External Storage. These directories are not access-restricted and data you store here can be easily read by other applications. These might be handy for storing non-sensitive high volume data, but keep in mind that the data contained in these directories is also removed once the user uninstalls your application.
The dedicated directories for your application on internal storage and external storage are together called app-specific directories, and you can read more about them here.
Drop a personal message in my inbox for pointing out inaccuracies, typos or for providing constructive criticism.