top of page
  • Writer's pictureHaseeb Hussain

Working with External File Storage


Creating UI

Create a new project and add the following code in the activity_main.xml file.

<?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:id="@+id/button2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:padding="16dp"
    >
    <Button
        android:id="@+id/btn_up"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="back"
        android:layout_alignParentTop="true"
        android:textSize="11sp"
        android:onClick="dirUP"
        />
    <Button
        android:id="@+id/btn_mk"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Make Directory"
        android:layout_toRightOf="@+id/btn_up"
        android:layout_marginLeft="10dp"
        android:layout_marginStart="10dp"
        android:textSize="11sp"
        android:onClick="makeDir"
        />
    <Button
        android:id="@id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:text="New File"
        android:onClick="newFile"
        android:layout_toRightOf="@+id/btn_mk"
        android:textSize="11sp"
        />
    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Click any button to start"
        android:layout_below="@+id/btn_up"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />



    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        >
        <Button
            android:id="@+id/btn_open"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Open"
            android:onClick="openFile"
            />

        <Button
            android:id="@+id/btn_delete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_toRightOf="@+id/btn_open"
            android:onClick="delete"
            android:text="Delete" />

        <Button
            android:id="@+id/btn_rename"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_toRightOf="@+id/btn_delete"
            android:text="Rename"
            android:onClick="rename"
            />

    </RelativeLayout>



</RelativeLayout>

Add Uses-permission Tag

add uses-permission tag for write to external storage in AndroidManifest.xml file.

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

Check and ask for storage permission

Android lolipop and greater needs permission to write to external storage, for this add the following we create a checkPermission method.


private void checkPermission() {
    if(Build.VERSION.SDK_INT>=23){
        if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
            requestPermissions(new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
        }
    }
}

in the time of asking user have choice to allow or decline the permission to check that what has been chosen by the use we use onRequestPermissionsResult.

add the following code in MainActivity.java file.


@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if(requestCode==1){
        if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
            loadFileList();
            Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(this, "Permission not granted", Toast.LENGTH_SHORT).show();
        }
    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

in this method we check the user choice and if the user allow the permission then we read and load the file. In order to load the file we called loadFileList() method.


call the checkPermission method in onCreate function to check for permission as soon as the activity is created


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    checkPermission();

}


Loading the files and folder

private void loadFileList() {
    TextView tv = findViewById(R.id.textview);
    tv.setText("");
    if(currentDir!=null){
        for (File obj : currentDir.listFiles()){
            if(obj.isDirectory()){
                tv.setText(tv.getText()+"\n"+obj.getName()+" > ");
            }else{
                tv.setText(tv.getText()+"\n"+obj.getName());
            }
        }
    }
}

this code load the current directory file list and distinguish the files and directories and show it in the TextView.


File currentDir = Environment.getExternalStorageDirectory();

add the above line of code just before the onCreate method.


Creating new File

public void newFile(View view) {

    AlertDialog.Builder dailog = new AlertDialog.Builder(this);
    LinearLayout layout = new LinearLayout(this);
    layout.setOrientation(LinearLayout.VERTICAL);
    EditText fileName = new EditText(this);
    EditText fileContent = new EditText(this);
    layout.addView(fileName);
    layout.addView(fileContent);
    dailog.setView(layout);
    dailog.setTitle("Create New File");
    dailog.setPositiveButton("Create", (dialog, which) -> {
        writeFile(fileName.getText().toString(),fileContent.getText().toString());
        loadFileList();
    }).setNegativeButton("Cancel",(dialog,which)->{
        dialog.cancel();
    }).show();


}

the newFile method open up the dialog box and ask the file name and file content and call the writeFile method.

private void writeFile(String fileName, String fileContent) {

    File file = new File(currentDir,fileName);
    try {
        FileOutputStream fs = new FileOutputStream(file);
        PrintWriter pw = new PrintWriter(fs);
        pw.println(fileContent);
        pw.flush();
        pw.close();
        fs.close();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }


}

writeFile method create a new file and add the file content to the file by FileOutputStream and PrinterWriter.


Opening Created File

public void openFile(View view) {
    AlertDialog.Builder dailog = new AlertDialog.Builder(this);
    LinearLayout layout = new LinearLayout(this);
    layout.setOrientation(LinearLayout.VERTICAL);
    EditText fileName = new EditText(this);
    layout.addView(fileName);
    dailog.setView(layout);
    dailog.setTitle("File/Directory Name to open");
    dailog.setPositiveButton("Open", (dialog, which) -> {
        readFile(fileName.getText().toString());

    }).setNegativeButton("Cancel",(dialog,which)->{
        dialog.cancel();
    }).show();

}

openFile method opens the dialog box and ask file name to open and call the readFile method


private void readFile(String fileName) {
    File file = new File(currentDir,fileName);
    if(file.isFile()){
        TextView tv = findViewById(R.id.textview);
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader(file));
            String line;
            while ( (line = br.readLine()) != null){
                stringBuilder.append(line);
                stringBuilder.append("\n");

            }
            br.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        tv.setText(stringBuilder.toString());

    }else{
        currentDir = file;
        loadFileList();
    }
}

readFile method check if the file is a file then get the content with the help of StringBuilder and BufferedReader to load the file content otherwise it changes the directory and load the directory file list.


Renaming a File / Directory

public void rename(View view) {

    AlertDialog.Builder dailog = new AlertDialog.Builder(this);
    LinearLayout layout = new LinearLayout(this);
    layout.setOrientation(LinearLayout.VERTICAL);
    EditText oldName = new EditText(this);
    oldName.setHint("Enter file name");
    EditText newName = new EditText(this);
    newName.setHint("Enter new name");
    layout.addView(oldName);
    layout.addView(newName);
    dailog.setView(layout);
    dailog.setTitle("Rename File / Folder");
    dailog.setPositiveButton("Rename", (dialog, which) -> {
        File oldFile = new File(currentDir,oldName.getText().toString());
        File newFile = new File(currentDir,newName.getText().toString());
        oldFile.renameTo(newFile);
        loadFileList();
    }).setNegativeButton("Close", (dialog, which) -> {
        dialog.cancel();
    }).show();

}

rename method gets the file old name and new name and rename the file using renameTo method


Deleting a Created File

public void delete(View view) {
    AlertDialog.Builder dialog = new AlertDialog.Builder(this);
    LinearLayout layout = new LinearLayout(this);
    layout.setOrientation(LinearLayout.VERTICAL);
    EditText fileName = new EditText(this);
    fileName.setHint("Enter File Name to Delete");
    layout.addView(fileName);
    dialog.setView(layout);
    dialog.setTitle("Delete File");
    dialog.setPositiveButton("Delete", (dailog, which) -> {
        File file = new File(currentDir,fileName.getText().toString());
        file.delete();
        loadFileList();
    }).setNegativeButton("Close", (dailog, which) -> {
        dailog.cancel();
    }).show();

}

delete method ask the file name and delete the file using delete method.


Creating new Directory

public void makeDir(View view) {

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    LinearLayout layout = new LinearLayout(this);
    layout.setOrientation(LinearLayout.VERTICAL);
    EditText fileName = new EditText(this);
    fileName.setHint("Directory Name");
    layout.addView(fileName);
    builder.setView(layout);
    builder.setTitle("Create New Directory");
    builder.setPositiveButton("Create", (dailog, which) -> {
        File file = new File(currentDir,fileName.getText().toString());
        file.mkdir();
        loadFileList();
    }).setNegativeButton("Close", (dailog, which) -> {
        dailog.cancel();
    }).show();

}

makeDir method creates the new directory using mkdir method.


Go to Previous Directory

public void dirUP(View view) {
    currentDir = currentDir.getParentFile();
    loadFileList();
}

Add the Libraries

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.Manifest; 
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;

Android studio automatically adds the Libraries if not then add all the libraries at the very top of your MainActivity.java file. Don't duplicate the imports.


Hope this helps you to understand the File Class with external storage if you find any difficulties then you can write to me or you can follow the video tutorial for better understanding


Thank You.


Video Tutorial


https://youtu.be/8mDZdWgCqqs


Post: Blog2_Post
bottom of page