Grokking Android

Getting Down to the Nitty Gritty of Android Development

How to Correctly Store App-Specific Files in Android

By 30 Comments

Christophe Versieux (Waza_be) posted a rant about android developers' bad habit to store files directly on the root of the sd card. I completely agree with the post. It's bad usage to create app-specific folders directly at the root. If you install a lot of apps, the sd card's root gets cluttered fast.

One comment also mentioned that most tutorials do not cover the app-specific folders, so let me correct that with a short tutorial on how to do it correctly.

App-specific files vs. app-independent files

If you need to store files there are generally two usage types:

I will cover both types in more detail in the following sections. But in short I would characterize those types as follows: App-specific files are those that only are useful for as long as the app is installed (e.g. ebooks in a proprietary format). App-independent files on the other hand are those that the user cares about regardless of the specific app that created them (e.g. photos).

App-independent files

This type of data is stuff your user very likely cares about, even if your app is no longer installed on the device. Examples are photos shot, images processed or sketched, code-files edited, audio files bought and so on.

For most of these types, Android provides special directories. A full list of directories that Android provides out of the box can be seen in the documentation of the Environment class. Those fields all start with "DIRECTORY". E.g. DIRECTORY_MUSIC or DIRECTORY_PICTURES.

Those files always have to be stored on the sd card (or the equivalent partition for devices that have no sd card slot like the Google Nexus line). The reason is, that those files tend to be quite large, that they need to be world-readable and that they must not be stored in a directory that get's cleaned up when your app gets uninstalled. I will cover external storage in more detail in the following sections.

You can get access to the root of the sd card by calling the getExternalStorageDirectory() method on the Environment class.

And you can use getExternalStoragePublicDirectory(String type) to directly get a File object for any of the supported types:


It's the usual Java IO API from here on.

App-specific files

This type of files is for any kind of data that only this specific app can or should make use of. This could be proprietary files like ebooks, media files that should not be available through the normal media players (e.g. thumbnails for CD covers), downloaded magazines, database files, preferences and so on.

App-specific files can be stored internally or externally (on the sd card) and the Android API helps you to find the appropriate directories.

What's nice for app-specific folders that follow a certain naming convention is Android's cleanup mechanism. Android takes care to delete these folder when users uninstall your app. This way Android gets rid of unnecessary files and users do not have to clean up manually after any deinstallation.

Internal storage versus external storage

You should know that there are two app-specific folders for any app. The internal one which you can use for private files and the external one. External storage refers to the sd card of Android devices or the equivalent partition that devices with no sd card option offer (e.g. the Nexus line).

Internal storage space can be limited

Especially for larger files you should prefer the external storage option. You should do so because internal storage space can be very limited depending on the device of your user. A probably extreme example is my old LG Optimus One that has only about 300 MB of internal storage. But with a 16 GB sd card I have plenty of external storage. Even if this device is one of the worst examples regarding internal storage, there are plenty of devices out there that also come with little internal storage. Not everyone uses high-end phones.

Permissions for writing to external storage

Whenever you want to access files on the external storage you need permissions to do so. Add this permissions to your manifest file:

   android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
   android:name="android.permission.READ_EXTERNAL_STORAGE" />

The need to declare this permissions is a slight drawback compared to internal storage. Some users may be wary - especially if this adds to an already long list of permissions. But if you explain this in your app description you should be fine.

Note: For reading files of the sd card no permissions were needed prior to Jelly Bean. So you can leave this one out if your build target is lower than API level 16.

External storage might be unavailable

The biggest problem with external storage is, that it might be unmounted when you need it. That's obviously the case when the sd card is ejected but also when your device is mounted for file access to your computer. Because of this, you always have to check, if the external storage is currently available:

if (Environment.getExternalStorageState().equals(
      Environment.MEDIA_MOUNTED)) {
   // you can go on

Sometimes the external storage might be mounted read-only. If you only need to read data the following check is better suited for you:

if (Environment.getExternalStorageState().startsWith(
      Environment.MEDIA_MOUNTED)) {
   // you can go on

This works since the value of the final field Environment.MEDIA_MOUNTED_READ_ONLY is "mounted_ro". I actually do not like code, that uses knowledge of final fields' value. In my opinion it would have been better, had Google chosen to use an integer so that we could use final fields as bitmasks to test for the state.

Internal app-specific directories

Android creates a directory private to your app for you. Your shared preferences go in here, as well as your SQLite databases, native libraries or cached files.

All app-specific files are within a folder named


Within this folder some common sub-folders might exist - depending on what your app needs:

The Context class provides some methods you can use to create new directories, open InputStreams and so on. The following table lists these methods:

Methods to help you with internal storage
Method When to use
deleteFile(String name) Deletes the file with the given name
fileList() Returns a list of files
getDir(String name, int mode) Returns a file object to this directory. If the directory doesn't exist yet, it gets created.
getFilesDir() Returns a File object pointing to the files directory
openFileInput(String name) Opens an InputStream object to the file with the given name
openFileOutput(String name, int mode) Opens an OutputStream object to the file with the given name. The file gets created if it does not exists

Some methods use a mode parameter. This can be any of the following constants of the Context class:

These are int values and you can use the or operator ("|") to combine them - e.g. to append to a world readable file:


External app-specific directories

This is where Waza_be's rant comes into play - because too many apps ignore the correct handling of app-specific directories on external storage.

All external app-specific files should be stored within a folder named


Note that I use a relative path. This path is relative to the root of the sdcard. The convention of where sdcards are mounted, changed between Android releases.

It's always good practice to use API calls instead of hard-coded values, but the fact that the mount-point has changed in the past should make you even more cautious.

Now for external files there exists only one method you can use:

getExternalFilesDir(String type)

If you pass in a null value the File object will point to the files directory. If you add any of the directory constants of the Environment class, you will get a File object pointing to a sub-directory within your files directory. If the directory doesn't exits yet, Android creates it for you. If the external media is not mounted, the method returns null.

Note: This method has only been introduced with API Level 8 (that is Froyo or Android 2.2). In the next section I briefly touch on the issues you face when dealing with older devices.

Older devices

There are still devices out there on older versions, which you might want to support. In this case using the naming convention shown above is still a good idea.

Alas, neither the method getExternalFilesDir(String type) exists, nor does Android clean up after an app uninstall. But using the same naming convention still avoids too many irritating folders on the root of your sd card.


Many times you need to cache data you downloaded from the net or created within your app. Android allows you to use internal as well as external storage space to use the cache. But using the external storage can be risky, since your cache might be unavailable when you need it.

The Context object has two methods to get a File object for either the internal or the external cache directory:

You have to take care of the cache size yourself. Android deletes all files in both directories on an uninstallation of your app, but otherwise it's up to you to clean up any cache files no longer needed.

If Android is running low on internal storage it cleans up cache files first but the API states explicitly that you should not rely on Android to clean up for you!

With the external cache storage Android doesn't care at all. Even if the external storage is full, no cache files will be deleted.

Naming of the folder

The official naming convention for the folder contains your package name. Christophe Versieux (Waza_be) himself mentioned that he used to use the app name instead, since users are more familiar with the package name of the app.

Even though familiarity is something to consider, I do not agree with this statement. First of all the API call uses the package name, so why not use it. Only with this method you can rely to be on the safe side. Secondly Android only cleans up a folder using the package name. And finally you could get screwed since app names do not have to be unique. In this case you might end up doing stuff in your folder that clashes with the intentions of the other app.

Be aware of the ".nomedia"-switch

Android's MediaScanner regularly scans the sd card for any media files and adds these to the public list of media files. Thus images will show up in the Gallery app or music files in audio players.

But that's not always what you want. Sometimes those files really should be presented by your app only. That's where ".nomedia" comes into play. If a folder contains a file named ".nomedia" it will be skipped by the MediaScanner and any media files will thus not show up in the public media list.

That's another reason to use the standard app-specific folder. It contains the file ".nomedia" within the data directory so that any media files you add to your app-specific directory will not show up.

Lessons learned

In this tutorial you have heard about the difference between app-specific and app-independent files and how to apply this knowledge to Android.

Also you have seen how to use app-specific files on Android, and how to leverage the internal storage as well as the external storage.

In a follow up post I will cover how to add app-independent media files to the corresponding content providers, so that they show up immediately in the list of public media files. Stay tuned.

Minor changes due to comments by +Alexandre Roman and +Cyril Mottier to my G+ announcement of this post.

Wolfram Rittmeyer lives in Germany and has been developing with Java for many years.

He has been interested in Android for quite a while and has been blogging about all kind of topics around Android.

You can find him on Google+ and Twitter.

30 thoughts on “How to Correctly Store App-Specific Files in Android”

  1. Excellent blog. Was looking for something like this for long time. And already been using the App Specific way but was not sure if I was doing it right.

    1. Thanks, nil. I’m glad you like this post.

      And thanks for storing files the right way. Your users will appreciate it. And it helps the Android reputation and ecosystem in general if developers like you keep their users interests in mind. Great job!

  2. thanks of the article.. and yes this is a wonderful blog !!

    1. Always nice to read this kind of comments 🙂 Thanks, Shashank!

  3. Excellent, thanks for the post!

  4. Its really excellent blog. Wolfram Rittmeyer you are among few people who really have the true ability to write something. Previously you were developer…. but from now you are also a great author man 🙂

    Really nice and good blog with some nice posts.I have bookmarked it….

    Keep it up.

  5. Thanks for the blog – but I still have a question regarding Nexus 5.

    You mention “the equivalent partition for devices that have no sd card slot like the Google Nexus line”. How do I find this or us this?

    I am exporting data into a file. Depending on the approach the file is either under /data/data/ and not accessible (unless permission of the file would be changed) or on an emulated SD card which cannot be access from the PC.

    I would like to store the file under Android/data/ but I have not found a way to do this. getExternalFilesDir(null) only leads to the emulated card.

    It would be great if you were able to help.


  6. Very helpful for new developers in android. Thank you very much for this lesson!

  7. And what if you want to have app-specific media files?

  8. I would say very good article. Given us wonderful message which reduces our time in finding the write way of doing things in android. very kool. Great work!

  9. Hello sir, thanks for this post. I have one question,i wanted to save my application images to external memory card of mobile or tablet. But my problem is, The getExternalStorageDirectory() cannot give memory card path. so can you help me?Thank you.

    1. Wolfram Rittmeyer

      First you have to keep in mind that Android changed a lot as to how it treats external memory and what it considers to be “external” in recent versions.

      Furthermore you shouldn’t use the method getExternalStorageDirectory(). You should instead either use getExternalStoragePublicDirectory() for files public to all apps and for files which should survive even if the user uninstalls your app or Context.getExternalFilesDir() for files specific to your app.

      Note: Neither of those is hidden from other apps, of course. External memory is publicly viewable to all, even if it’s specific to your app.

  10. Nice article. I have one question regarding how to ind the external SD card path.

    1. I’m sorry. If you added code or something like this, then WordPress cut it off. Please repost your question without using any html/xml tags.

  11. Nice article.

  12. Thanks for the great blog entry. It cleared some confusion for me. I still have a problem though, maybe you can help me out. I’d like to store a image the user selected from the SD card to the internal storage to a sub-folder (not the root folder I get with getFilesDir()) – for example to /user12/gallery/public/.
    Do you have any idea/help how to achieve this? I just can’t seem to be able to put the pieces together.

  13. Nice work

  14. very nice explanation

  15. very nice explanation

    now i want to know how to create a folder of app name in device storage not in sd card as i have tried Environment methods bt phones having no sd card it fails to create file so please help me in this please

    1. There always is an app specific folder, that is only visible to your app. It’s within the /data/data folder. See the section “Internal app-specific directories” of this post.

  16. Yeah,well explained. But may i ask a doubt which is out of topic. But almost within. Please have a look at
    this image first

    Which is an output that i got from Opera browser when I was visiting a page. Have a look at the URL. It’s LHOST. .. What? How the image can be fetched from this URL? . How is this possible to display the image? Is this a cache file? If yes how it fetch the file using file://

  17. Thanks for giving such information. I want to know further detail about Internal Storage and that is.. how to get listing of Internal Storage directory in our application. I didn’t found anywhere. Hope you will help.
    Thanks in advance. 🙂

    1. If you just want a list of the files, use fileList() which returns an array of String object. Or you use getDataDir() to get access to the root of your private application folder. That returns a File object which you can use to recursively iterate over it.

      I’d prefer using the File object since you get more information that way: Like if the child a directory or a normal file, what the creation and modification dates are and so on. That is normal Java file handling and you should be able to find plenty of tutorials for how to do that.

  18. Hi Wolfram Rittmeyer!

    Very well explanations!

    I’ve a doubt, how do WhatsApp can create a folder on the tree at the same level of the folders like “Documents”, “Sounds”, “Movies”, etc?
    In my cellphone the paths on internal memory are:


    I didn’t see any examples like that on your explanation. Is there a third way to do that?

  19. nice,this blog is best to get idea for beginners ……….. best of luck

  20. Hello
    Excuse my bad english!
    I save one web site in a folder that I can read it localy in windows in offline. The home page index.html is open in the browser in offline, in URL I have: file:///D:/MesRessources/courses/sitedomain/index.html and this work fine, but when I copy this MesRessources folder in my samsung s5 phone data folder, when I open index.html my phone browser displays in URL this path: content://0@media/external/file/sitedomain/index.html , and I have a message displayed in body of navigator telling me that the file doesn’t exist. Is there an application or browser that I can install and that it can read my files like on windows?
    Thanks for help!

    1. Most likely you can access the sd-card content in Chrome using file:///sdcard/. I never did that, though.

      Anyhow: This has nothing to do with this post. This post is intended to bring Android developers to store files in ways that do not annoy users 🙂

      1. You are the best! Thank you for your answer, it helped me a lot. I installed chrome and tried to access the index.html file from my resources folder from a folder named “storage/emulated” that I found on the root: file:///storage/emulated/0/MesRessources/courses/sitedomain/index.html and it works perfectly (only in chrome browser), and now I can read my resources on my small screen 🙂 thank you very very much and I apologize for asking a question that has nothing to do with your post but somewhere I was not wrong because thanks to you I found my happiness.

  21. Thank you so much for writing this.

    Based on the Android docs and StackOverflow answers, I never would have guessed that it’s this straight forward.

    You laid it out perfectly to help categorize and understand differences easily.

    Our application downloads a lot of photos and videos to operate, we needed to use the app-specific external storage directory. Who knew it was a single command that checks on the state, gets the directory and creates any subdirectories that you need as well. Brilliant!

    Please keep writing and educating.


Leave a Reply

Your email address will not be published. Required fields are marked *