How to save files on external storage in Android?


Introduction

In android devices the most useful feature is to store and read the files within the device storage or an external storage. This allows users to expand their device storage capacity so that they can store and retrieve files according to their convenience and can use them accordingly. In this article we will take a look at How to save files on external storage in Android.

Implementation

We will be creating a simple application in which we will be creating a text view for displaying the heading of our application.After that we will be creating an edit text field from which we will be reading the data which the user wants to store within the external storage. Then we will be adding a button which is used to store this data in the form of a file in the device external storage or an sd card. After that we will be displaying a text view and one more button which is used to read the data. When the user clicks on this read data button we will be reading the file from the external storage and setting the data from that file within our text view. Now let's move towards android studio for creating a new project.

Step 1 : Creating a new project in Android Studio

Navigate to Android studio as shown in below screen. In the below screen click on New Project to create a new Android Studio Project.

After clicking on New Project you will get to see the below screen.

Inside this screen we have to simply select Empty Activity and click on Next. After clicking on next you will get to see the screen below.

Inside this screen we have to simply specify the project name. Then the package name will be generated automatically.

Note : Make sure to select the Language as Java.

After specifying all the details click on Finish to create a new Android studio project.

Once our project has been created we will get to see 2 files which are open i.e activity_main.xml and MainActivity.java file.

Step 2 : Working with activity_main.xml

Navigate to activity_main.xml. If this file is not visible. To open this file. In the left pane navigate to app>res>layout>activity_main.xml to open this file. After opening this file. Add the below code to it. Comments are added in the code to get to know in detail.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent">
   <!-- on below line creating the heading of our application -->
   <TextView
       android:id="@+id/idTVHeading"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_margin="10dp"
       android:layout_marginTop="90dp"
       android:padding="8dp"
       android:text="Save File in External Storage in Android"
       android:textAlignment="center"
       android:textColor="@color/black"
       android:textSize="20sp"
       android:textStyle="bold" />
   <!-- on below line creating an edit text for storing the data in the file -->
   <EditText
       android:id="@+id/idEdtMessage"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_below="@id/idTVHeading"
       android:layout_margin="10dp"
       android:hint="Enter the data to be saved in the file.."
       android:lines="4" />
   <!-- on below line creating a button to save this image view in external storage-->
   <Button
       android:id="@+id/idBtnSave"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_below="@id/idEdtMessage"
       android:layout_margin="10dp"
       android:text="Save File To External Storage"
       android:textAllCaps="false" />
   <!-- on below line creating a text view for displaying the file data -->
   <TextView
       android:id="@+id/idTVFileData"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_below="@id/idBtnSave"
       android:layout_centerHorizontal="true"
       android:layout_margin="10dp"
       android:padding="4dp"
       android:text="File Data will appear here"
       android:textAlignment="center"
       android:textColor="@color/black"
       android:textSize="18sp" />
   <!-- on below line creating a button to view the file stored in external storage-->
   <Button
       android:id="@+id/idBtnView"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_below="@id/idTVFileData"
       android:layout_margin="10dp"
       android:text="View File Data"
       android:textAllCaps="false" />
</RelativeLayout>

Explanation : In the above code we are creating a root layout as a Relative Layout. Inside this layout we are creating a text view which is used to display the heading of our application. After that we have created an edit text field which is used to get the user input which we have to store in the file. After that we are creating a button which is used to generate a file and store the data from the text input field in our sd card or external storage. After that we are creating a text view and a button. We will be using a button to read the file from external storage and we will be displaying the data from that file within our text view.

Step 3 : Adding permissions in AndroidManifest.xml file

Navigate to app>AndroidManifest.xml file and add below permissions to it in manifest tag to read sms.

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

Step 4 : Working with MainActivity.java file

Navigate to MainActivity.java. If this file is not visible. To open this file. In the left pane navigate to app>res>layout>MainActivity.java to open this file. After opening this file. Add the below code to it. Comments are added in the code to get to know in detail.

package com.example.java_test_application;
import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.IntentSender;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Telephony;
import android.text.TextUtils;
import android.util.Log;
import android.util.Patterns;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.credentials.Credential;
import com.google.android.gms.auth.api.credentials.CredentialPickerConfig;
import com.google.android.gms.auth.api.credentials.CredentialRequest;
import com.google.android.gms.auth.api.credentials.CredentialRequestResult;
import com.google.android.gms.auth.api.credentials.Credentials;
import com.google.android.gms.auth.api.credentials.CredentialsClient;
import com.google.android.gms.auth.api.credentials.CredentialsOptions;
import com.google.android.gms.auth.api.credentials.HintRequest;
import com.google.android.gms.auth.api.credentials.IdentityProviders;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import org.w3c.dom.Text;
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 java.util.Date;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
   // creating variable for edit text on below line.
   private EditText msgEdt;
   // creating variables for button on below line.
   private Button saveFileBtn, viewFileBtn;
   // creating variable for text view on below line to display the data from the file.
   private TextView dataTV;
   File externalFile;
   private String filename = "file.txt";
   private String filepath = "files";
   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       // initializing variables for text view on below line.
       saveFileBtn = findViewById(R.id.idBtnSave);
       viewFileBtn = findViewById(R.id.idBtnView);
       msgEdt = findViewById(R.id.idEdtMessage);
       dataTV = findViewById(R.id.idTVFileData);
       // on below line we are checking if the external storage is available on the device and the external storage is not read only.
       if (!isExternalStorageAvailable() || isExternalStorageReadOnly()) {
           // if the external storage is not avialable then we are displaying the toast message on below line.
           Toast.makeText(this, "External storage not available on the device..", Toast.LENGTH_SHORT).show();
       } else {
           // on below line we are initializing external file variable and specifying the file path along with file name.
           externalFile = new File(getExternalFilesDir(filepath), filename);
       }
       // on below line adding click listener for save file button.
       saveFileBtn.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               // on below line we are checking if the edit text is empty or not.
               if (msgEdt.getText().toString().isEmpty()) {
                   // if the edit text is empty we are displaying a toast message.
                   Toast.makeText(MainActivity.this, "Please enter your message..", Toast.LENGTH_SHORT).show();
               } else {
                   // on below line checking for the file output stream.
                   try {
                       // on below line creating a file output stream.
                       FileOutputStream fos = new FileOutputStream(externalFile);
                       // on below line writing the data from edit text in file output stream/
                       fos.write(msgEdt.getText().toString().getBytes());
                       // on below line closing the file output stream.
                       fos.close();
                       // on below line displaying toast message as file has been saved.
                       Toast.makeText(MainActivity.this, "File saved to External Storage..", Toast.LENGTH_SHORT).show();
                       // on below line handling the exception.
                   } catch (IOException e) {
                       e.printStackTrace();
                   }
               }
           }
       });
       // on below line adding click listener for view file button.
       viewFileBtn.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               // on below line creating a string variable named as file data.
               String fileData = "";
               try {
                   // on below line creating a variable for file input stream and passing the file path to it.
                   FileInputStream fis = new FileInputStream(externalFile);
                   // on below line creating and initializing variable for data input stream.
                   DataInputStream in = new DataInputStream(fis);
                   // on below line creating and initializing variable for buffer reader.
                   BufferedReader br = new BufferedReader(new InputStreamReader(in));
                   // on below line reading the data from file and appending it to the file data variable.
                   String strLine;
                   while ((strLine = br.readLine()) != null) {
                       fileData = fileData + strLine;
                   }
                   // on below line setting data from variable to our text view.
                   dataTV.setText(fileData);
                   in.close();
                   // on below line handling the exception.
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       });
   }
   // on below line creating a method to checking weather external storage is read only.
   private static boolean isExternalStorageReadOnly() {
       // on below line getting external storage and checking if it is media mounted read only.
       String extStorageState = Environment.getExternalStorageState();
       if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {
           return true;
       }
       return false;
   }
   // on below line creating a method to check weather external storage is available or not.
   private static boolean isExternalStorageAvailable() {
       // on below line checking external storage weather it is available or not.
       String extStorageState = Environment.getExternalStorageState();
       if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {
           return true;
       }
       return false;
   }
}

Explanation : In the above code firstly we are creating variables for our edit text, button and text view. After that we are creating a variable for externalFile, file name and file path as a string variable. Now we will get to see the onCreate method. This is the default method of every android application. This method is called when the application view is created. Inside this method we are setting the content view i.e the layout file named activity_main.xml to set the UI from that file. Inside the onCreate method we are initializing the button, text view and edit text variables with the id which we have given in our activity_main.xml file.

After that we are checking whether the external storage is present in the device and do we have permissions to read and write the data in it. If the user is having external storage present in the device then we are initializing the external file variable with the file path and file name. After that we are adding a click listener for the save file button, inside the on click method we are checking whether the edit text field is empty or not. If the edit text field is not empty then we are creating a file output stream and storing the data from the text input field in that file.

After that we are adding a click listener for our view file button. Inside the click listener method we are calling file input stream to read the data from the file which we have stored and we are setting that data from the file in the text view which we have created. Lastly we have created two methods which are used to check whether external storage is available and also we can read the external storage.

After adding the above code now we have to simply click on the green icon in the top bar to run our application on a mobile device.

Note : Make sure you are connected to your real device or emulator.

Output

Conclusion

In the above article we have taken a look on How to save a file on external storage in Android.

Updated on: 09-May-2023

3K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements