How do I read and write to user accessible directory in android code?

0

I am new to app development and want to read and write files from a user accessible directory such as documents on Android. Everything I've found online doesn't work or writes to hidden files.

I want to be able to read basic text files and pictures from a directory and sub-directories for processing. I need to read from the internal storage in the same directories as DCIM, Download, Music, etc.

I need a full breakdown of how to do it. I'm coding for Android 6 and up on Android Studio. I only have access to internal storage on my dev phone.

Thanks in advance. Sorry for being a noob.

I don't really know what is applicable for background. I don't fully understand how the Android file system and permissions work.

My dev phone is a Google Pixel 3a with android 10.

Here is my project code: Manifest:

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

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

    <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/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Main Activity:

package nbradham.rwtest;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;

import androidx.annotation.NonNull;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class MainActivity extends Activity {

    private final int STORAGE_PERMISSION_REQUEST_CODE = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        System.out.println("############");
        requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_REQUEST_CODE);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[]
            permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        System.out.println("Perm...");
        switch (requestCode) {
            case STORAGE_PERMISSION_REQUEST_CODE:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        System.out.println("Reading...");
                        try {
                            File f = new File(Environment.getExternalStorageDirectory(), "Download/loadme.txt");
                            System.out.println(f.getAbsolutePath());
                            BufferedReader br = new BufferedReader(new FileReader(f));

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

                break;
            default:
                break;
        }
    }
}

Here is the output:


10/02 18:34:50: Launching 'app' on Google Pixel 3a.
$ adb shell am start -n "nbradham.rwtest/nbradham.rwtest.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Waiting for process to come online...
Connected to process 5611 on device 'google-pixel_3a-93KAY0C208'.
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
I/nbradham.rwtes: Late-enabling -Xcheck:jni
E/nbradham.rwtes: Unknown bits set in runtime_flags: 0x8000
I/System.out: ############
I/Adreno: QUALCOMM build                   : 4a00b69, I4e7e888065
    Build Date                       : 04/09/19
    OpenGL ES Shader Compiler Version: EV031.26.06.00
    Local Branch                     : 
    Remote Branch                    : 
    Remote Branch                    : 
    Reconstruct Branch               : 
    Build Config                     : S P 8.0.6 AArch64
I/Adreno: PFP: 0x016ee183, ME: 0x00000000
W/Gralloc3: mapper 3.x is not supported
I/System.out: Perm...
    Reading...
I/System.out: /storage/emulated/0/Download/loadme.txt
W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Download/loadme.txt: open failed: EACCES (Permission denied)
        at libcore.io.IoBridge.open(IoBridge.java:496)
        at java.io.FileInputStream.<init>(FileInputStream.java:159)
        at java.io.FileReader.<init>(FileReader.java:72)
        at nbradham.rwtest.MainActivity.onRequestPermissionsResult(MainActivity.java:39)
W/System.err:     at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:8264)
        at android.app.Activity.dispatchActivityResult(Activity.java:8114)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4838)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4886)
        at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
    Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
        at libcore.io.Linux.open(Native Method)
        at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
W/System.err:     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:252)
        at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
        at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7255)
        at libcore.io.IoBridge.open(IoBridge.java:482)
        ... 17 more
java
android
file
io
filesystems
asked on Stack Overflow Oct 2, 2019 by user3696181 • edited Oct 3, 2019 by user3696181

1 Answer

0

You have to Put Permission First in Manifiest:

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

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

then you have to ask permission in runtime on above marshmellow device:

private void requestPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(new String[] {
                    android.Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_REQUEST_CODE);
        } else {
           // do your code if permission granteed
        }
    }

and then you have to catch the permission on onActvitiyResult overriden method

 @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[]
            permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode) {
            case STORAGE_PERMISSION_REQUEST_CODE:
                if (grantResults.length > 0 && permissions[0].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE) && grantResults.length > 0 && permissions[1].equals(Manifest.permission.READ_EXTERNAL_STORAGE)) {
                    // check whether storage permission granted or not.
                    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                       // do you stuff if your permission is granted
                    }
                }
                break;
            default:
                break;
        }
    }
answered on Stack Overflow Oct 2, 2019 by natsujay

User contributions licensed under CC BY-SA 3.0