Steph
Steph

Reputation: 21

Unable to write to external storage; Access is denied

I have a class which stores images downloaded from Facebook when the app is started for the first time. What I do is that I would use a class to create a folder (if it does not exist before) and store all the images there.

Important I've had success on several devices of different API (all below 23). Files are written and retrieved successfully. Lately I have a new phone which uses 6.0 (API 23) and somehow the code to write files into storage system no longer works. I can no longer create the folder in the sdcard and that leads to the error.

As an added information, the phone is a rooted nexus 5X, not a external SD card. The app runs on API 23 and dangerous permission including storage is properly authorized before the app can even be used.

Using the tried and true method of getExternalStorageDirectory, which returns emulated/0/. The Environment.MEDIA_MOUNTED indicates that access is granted to the storage. The problem is the moment I try to create a folder it tells me i cannot do so.

.canwrite indicates that the mkdirs directory I am trying to create is not accessible

For your reference, my manifest:

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

My method that writes to the external storage:

public static String storeImage(Bitmap bitmap, String filename) {
    String stored = null;
    String folder_main = "Samepage";
    String root = Environment.getExternalStorageDirectory().toString();
    String state = Environment.getExternalStorageState();
    Log.i(TAG,"Storage state is " + state);
    File folder = new File(root + "/Samepage");
    Log.i(TAG, folder.toString());

    if (!Environment.MEDIA_MOUNTED.equals(state)) {
        Log.e(TAG,"Storage is not mounted!");
    }

    if (folder.canWrite()) {
        Log.i(TAG, "External storage is accessible");

        if (!folder.exists()) {
            folder.mkdirs();

        }
    } else 
        Log.e(TAG, "Default storage is not accessible");


    File sdcard = Environment.getExternalStorageDirectory();
    if (folder.exists()) {
        File file = new File(root, filename + ".png");
        if (file.exists())
            file.delete();

        try {
            FileOutputStream out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
            out.flush();
            out.close();
            stored = "success";
            Log.i(TAG, "User image created successfully");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    return stored;
}

Upvotes: 0

Views: 7674

Answers (1)

Hendra Anggrian
Hendra Anggrian

Reputation: 5848

On API 23+, I would suggest running this function before any external storage operation:    

private static final int REQUESTCODE_STORAGE_PERMISSION = 999999999;

private static boolean storagePermitted(Activity activity) {

    Boolean readPermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
    Boolean writePermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;

    if (readPermission && writePermission) {
        return true;
    }

    ActivityCompat.requestPermissions(activity, new String[]{ Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }, REQUESTCODE_STORAGE_PERMISSION);
    return false;
}

This method requests permission to read and write to external storage and returns a true if you should perform the operation. As of API 23 external storage permissions have been disabled by default.

For further reading: developer.android.com/training/permissions/requesting.html

Upvotes: 3

Related Questions