Read and write files in app private storage

This post shows how to create a text file in private app storage and access all files in private app storage.

In AndroidManifest.xml add a FileProvider.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.pickfile">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.PickFile">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".PrivateStorage"/>
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.pickfile.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>
    </application>

</manifest>

In xml folder in res/ and in res/xml/ add a file provider_paths.xml.

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

Create your layout in activity_main.xml.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/edittext1"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="#efefcf"
        android:padding="8dp"
        android:gravity="start"
        app:layout_constraintBottom_toTopOf="@+id/edittext2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <EditText
        android:id="@+id/edittext2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="#efefef"
        android:padding="8dp"
        android:textSize="18sp"
        android:hint="file_name"
        android:gravity="start"
        app:layout_constraintTop_toBottomOf="@id/edittext1"
        app:layout_constraintBottom_toTopOf="@+id/button1"
        app:layout_constraintEnd_toStartOf="@id/textview1"
        app:layout_constraintStart_toStartOf="parent" />
    <TextView
        android:id="@+id/textview1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:padding="8dp"
        android:text=".txt"
        android:textStyle="bold"
        android:textSize="18sp"
        app:layout_constraintBottom_toTopOf="@+id/button1"
        app:layout_constraintEnd_toEndOf="parent" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="4dp"
        android:text="Save file"
        android:textSize="16sp"
        app:layout_constraintTop_toBottomOf="@id/edittext2"
        app:layout_constraintEnd_toStartOf="@id/button2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"/>

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="4dp"
        android:text="Private storage"
        android:textSize="16sp"
        app:layout_constraintTop_toBottomOf="@id/edittext2"
        app:layout_constraintStart_toEndOf="@id/button1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

In MainActivity.java use following codes.

package com.example.pickfile;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    EditText edittext1, edittext2;

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

        Button button1 = findViewById(R.id.button1);
        Button button2 = findViewById(R.id.button2);
        edittext1 = findViewById(R.id.edittext1);
        edittext2 = findViewById(R.id.edittext2);

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String folder = getExternalFilesDir(null).getAbsolutePath() + "/";
                String filename = "newfile.txt";
                if (!edittext2.getText().toString().equals("")){
                   filename = edittext2.getText().toString() + ".txt";
                }
                File newfile = new File(folder, filename);

                String text = edittext1.getText().toString();

                try {
                    FileWriter myWriter = new FileWriter(newfile);
                    myWriter.write(text);
                    myWriter.close();
                    Toast.makeText(getApplicationContext(),
                            "Successfully wrote to the file.", Toast.LENGTH_SHORT).show();
                } catch (IOException e){
                    Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
                }
            }
        });

        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, PrivateStorage.class);
                startActivity(intent);
            }
        });

    }

}

Create private_storage.xml in res/layout/ folder.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:id="@+id/recyclerview1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Create recycler_item.xml in res/layout/ folder.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#ffffcc">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textSize="22sp"
        android:textColor="#1f1eee"
        android:padding="4dp"
        android:gravity="start"
        app:layout_constraintEnd_toStartOf="@id/imageView1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="40dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/textView1"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/ic_more_vert_black_24dp" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textSize="18sp"
        android:textColor="#6f6e6e"
        android:padding="4dp"
        android:paddingTop="2dp"
        android:gravity="start"
        app:layout_constraintEnd_toStartOf="@id/imageView1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textView1" />
</androidx.constraintlayout.widget.ConstraintLayout>

Create new ja PrivateStorage.java use following codes.

package com.example.pickfile;

import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.widget.PopupMenu;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import java.io.File;

public class PrivateStorage extends AppCompatActivity {

    private RecyclerView mRecyclerView;
    private File[] allfiles;
    CustomAdapter mAdapter;

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

        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview1);

        RecyclerView.LayoutManager mLayoutManager= new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);

        mRecyclerView.addItemDecoration(
                new DividerItemDecoration(getApplicationContext(),
                        DividerItemDecoration.VERTICAL));

        refreshAdapter();
    }

        private void refreshAdapter() {
            String folder = getExternalFilesDir(null).getAbsolutePath() + "/";
            File directory = new File(folder);
            allfiles = directory.listFiles();
            mAdapter = new CustomAdapter(allfiles);
            mRecyclerView.setAdapter(mAdapter);
        }

        public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {

            private final File[] files_list;

            public CustomAdapter(File[] dataSet) {
                files_list = dataSet;
            }

            @Override
            public int getItemCount() {
                return files_list.length;
            }

            public class ViewHolder extends RecyclerView.ViewHolder {
                private final TextView textView1, textView2;
                private final ImageView imageView;

                public ViewHolder(View v) {
                    super(v);
                    textView1 = v.findViewById(R.id.textView1);
                    textView2 = v.findViewById(R.id.textView2);
                    imageView = v.findViewById(R.id.imageView1);

                }
            }

            @Override @NonNull
            public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
                // Create a new view.
                View v = LayoutInflater.from(viewGroup.getContext())
                        .inflate(R.layout.recycler_item, viewGroup, false);

                return new ViewHolder(v);
            }

            @Override
            public void onBindViewHolder(ViewHolder viewHolder, final int position) {
                String filepath = files_list[position].getAbsolutePath();
                String filename = filepath.substring(filepath.lastIndexOf("/")+1);

                viewHolder.textView1.setText(filename);
                viewHolder.textView2.setText(filepath);

                viewHolder.imageView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View _v) {
                        PopupMenu popup = new PopupMenu(PrivateStorage.this, _v);
                        Menu menu = popup.getMenu();
                        menu.add("Open");
                        menu.add("Share");
                        menu.add("Delete");

                        popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener(){
                            @Override
                            public boolean onMenuItemClick(MenuItem item){
                                switch (item.getTitle().toString()){
                                    case  "Open":
                                        Intent intent = new Intent(Intent.ACTION_VIEW);
                                        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                                        intent.setDataAndType(FileProvider.getUriForFile(
                                                PrivateStorage.this,
                                                getApplicationContext().getPackageName() + ".provider",
                                                files_list[position]), "text/*");
                                        try {
                                            startActivity(intent);
                                        } catch (ActivityNotFoundException e) {
                                            Toast.makeText(getApplicationContext(),
                                                    "No app found to open this file", Toast.LENGTH_SHORT).show();
                                        }
                                        break;
                                    case "Share":
                                        Intent iten = new Intent(android.content.Intent.ACTION_SEND);
                                        iten.setType("text/*");
                                        iten.putExtra(Intent.EXTRA_STREAM,
                                                FileProvider.getUriForFile(
                                                        PrivateStorage.this,
                                                        getApplicationContext().getPackageName() + ".provider",
                                                        files_list[position]));
                                        startActivity(Intent.createChooser(iten, "Send to"));
                                        break;
                                    case "Delete":
                                        if (files_list[position].delete()){
                                            refreshAdapter();
                                        }
                                        break;
                                }
                                return true;
                            }
                        });
                        popup.show();
                    }
                });
            }

        }

}

Now run the app.

Access files in app’s private storage

Leave a Reply