Android external storage can be used to write and save data, read configuration files etc. This article is continuation of the Android Internal Storage tutorial in the series of tutorials on structured data storage in android.
External storage such as SD card can also store application data, there’s no security enforced upon files you save to the external storage. In general there are two types of External Storage:
All applications can read and write files placed on the external storage and the user can remove them. We need to check if the SD card is available and if we can write to it. Once we’ve checked that the external storage is available only then we can write to it else the save button would be disabled.
Firstly, we need to make sure that the application has permission to read and write data to the users SD card, so lets open up the AndroidManifest.xml
and add the following permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Also, external storage may be tied up by the user having mounted it as a USB storage device. So we need to check if the external storage is available and is not read only.
if (!isExternalStorageAvailable() || isExternalStorageReadOnly()) {
saveButton.setEnabled(false);
}
private static boolean isExternalStorageReadOnly() {
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {
return true;
}
return false;
}
private static boolean isExternalStorageAvailable() {
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {
return true;
}
return false;
}
getExternalStorageState()
is a static method of Environment
to determine if external storage is presently available or not. As you can see if the condition is false we’ve disabled the save button.
The activity_main.xml layout is defined as follows:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Reading and Writing to External Storage"
android:textSize="24sp"/>
<EditText android:id="@+id/myInputText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10" android:lines="5"
android:minLines="3" android:gravity="top|left"
android:inputType="textMultiLine">
<requestFocus />
</EditText>
<LinearLayout
android:layout_width="match_parent" android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1.0"
android:layout_marginTop="20dp">
<Button android:id="@+id/saveExternalStorage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="SAVE"
android:layout_weight="0.5"/>
<Button android:id="@+id/getExternalStorage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:text="READ" />
</LinearLayout>
<TextView android:id="@+id/response"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:padding="5dp"
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
Here apart from the save and read from external storage buttons we display the response of saving/reading to/from an external storage in a textview unlike in the previous tutorial where android toast was displayed. The MainActivity.java class is given below:
package com.journaldev.externalstorage;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import android.os.Bundle;
import android.app.Activity;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
EditText inputText;
TextView response;
Button saveButton,readButton;
private String filename = "SampleFile.txt";
private String filepath = "MyFileStorage";
File myExternalFile;
String myData = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
inputText = (EditText) findViewById(R.id.myInputText);
response = (TextView) findViewById(R.id.response);
saveButton =
(Button) findViewById(R.id.saveExternalStorage);
saveButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
FileOutputStream fos = new FileOutputStream(myExternalFile);
fos.write(inputText.getText().toString().getBytes());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
inputText.setText("");
response.setText("SampleFile.txt saved to External Storage...");
}
});
readButton = (Button) findViewById(R.id.getExternalStorage);
readButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
FileInputStream fis = new FileInputStream(myExternalFile);
DataInputStream in = new DataInputStream(fis);
BufferedReader br =
new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null) {
myData = myData + strLine;
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
inputText.setText(myData);
response.setText("SampleFile.txt data retrieved from Internal Storage...");
}
});
if (!isExternalStorageAvailable() || isExternalStorageReadOnly()) {
saveButton.setEnabled(false);
}
else {
myExternalFile = new File(getExternalFilesDir(filepath), filename);
}
}
private static boolean isExternalStorageReadOnly() {
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {
return true;
}
return false;
}
private static boolean isExternalStorageAvailable() {
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {
return true;
}
return false;
}
}
Also if the external storage is not available we disable the save button using the if condition that was discussed earlier in this tutorial. Below is our application running in android emulator, where we are writing data to file and then reading it. Note: Make sure your Android Emulator is configured such that it has a SD card as shown in the image dialog from AVD below. Go to Tools->Android->Android Virtual Device, edit configurations->Show Advance Settings. This brings an end to this tutorial. We’ll discuss storage using Shared Preferences in the next tutorial. You can download the final Android External Storage Project from the below link.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
Thank You!
- Hanan
hi anupam, thank you for your clear explanation and coding -and you made me nervous, when i received the text toast: " read from internal storage " ( its a typo ) ha: its still the external - i am happy. i like to buy you a drink! thank you rudolf hallerhandel@gmail.com
- rudolf
Hey your tutorial is awesome and working but i cant find the file, the folder “MyFileStorage” is empty but it’s still working… Can you tell me where i can find the file?
- Hugo
hi anupam , i need your help if possible. i have get image using json web services. now i need to download this when click download button and image an store in my mobile storage . how can i perform this task. YOU CAN REPLY IN MY EMAIL .
- Ankur Bhoot
hii sir I want make app for English grammar can u tell how can I do it sorry for my poor English
- hackerassh
Layout and layout parameters are not connected to java file in the above code .
- babu
It is irritating beyond belief that a popup for “FREE eBook” covers up part of the display without even showing a Close button/box. Rest assured I will never buy anything advertised on this web site because of htat.
- Matthew Johnson
hi you! How to export data saved in sqlite to txt file Thank you !
- TRINH TRINH
thanks for share this :D
- pradana
Hello, great tutorial but you only covered the primary external storage, what about the secondary one?
- Farhan