External Storage

External Storage is useful to store the data files publicly on the shared external storage using the FileOutputStream object. After storing the data files on external storage, we can read the data file from external storage media using a FileInputStream object.

The data files saved in external storage are word-readable and can be modified by the user when they enable USB mass storage to transfer files on a computer.


Important Note: It is necessary to add external storage the permission to read and write. For that you need to add permission in android Manifest file. Open AndroidManifest.xml file and add permissions to it just after the package name.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Note: To avoid crashing app it is required to check before whether storage SD card is available for read & write operations. getExternalStorageState() method is used to determine the state of the storage media i.e SD card is mounted, is it readable, it is writable etc... as shown in below code snippet:

public boolean canWriteExternalStorage() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        // Read and write operation possible
        return true;
    }

    if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        // Read operation possible
        return false;
    }

    return false;
}

public boolean canReadExternalStorage() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        // Read operation possible
        return true;
    }

    return false;
}


Methods to Store Data In Android

  • getExternalStorageDirectory(): Older way to access external storage in API Level less than 7. It is absolute now and not recommended. It directly get the reference to the root directory of your external storage or SD Card.
  • getExternalFilesDir(type): It is recommended way to enable us to create private files specific to app and files are removed as app is uninstalled. Example is app private data.
  • getExternalStoragePublicDirectory(): This is current recommended way that enable us to keep files public and are not deleted with the app uninstallation. Example images clicked by the camera exists even we uninstall the camera app.

In android, by using getExternalStoragePublishDirectory() method we can access the files from appropriate public directory by passing the type of directory we want, such as DIRECTORY_MUSIC, DIRECTORY_PICTURES, DIRECTORY_RINGTONES, etc. based on our requirements.

Following example show you how to write file into Downloads directory.

boolean canWrite = canWriteExternalStorage();
if (canWrite) {
    File downloadFolder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
    // make directories iff not exists
    if (!downloadFolder.mkdirs()) {
        Toast.makeText(this, "Directory not created", Toast.LENGTH_SHORT).show();
    }
    // Get the directory for the user's public downloads directory.
    File file = new File(downloadFolder, "sample.txt");

    try {
        FileOutputStream fos = new FileOutputStream(file);
        fos.write("This is example of Android Internal Storage".getBytes());
        fos.flush();
        fos.close();

        Toast.makeText(this, "File written successfully", Toast.LENGTH_SHORT).show();
    } catch (IOException e) {
        Toast.makeText(this, "File writing error: " + e.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
    }
}


Following example show you how to read file from Downloads directory.

boolean canRead = canReadExternalStorage();
if(canRead) {
    File downloadFolder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);

    // Get the directory for the user's public downloads directory.
    File file = new File(downloadFolder, "sample.txt");
    try {
        FileInputStream fis = new FileInputStream(file);

        int ch;
        StringBuffer strBuff = new StringBuffer();
        while ((ch = fis.read()) != -1) {
            strBuff.append((char)ch);
        }

        fis.close();

        // display saved file data
        Toast.makeText(this, "File data: " + strBuff.toString(), Toast.LENGTH_SHORT).show();
    } catch (IOException e) {
        Toast.makeText(this, "File reading error: " + e.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
    }
}