AskQuestions
AskQuestions

Reputation: 173

Android - Permission Denied for creating new file

Im trying to create a file in Android, and even after following all the other answers im still getting permission denied. Error happens in saveImage() method.

 // STATICS
 private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState)
        verifyStoragePermissions(this);
    }

  //HERE IS THE METHOD THAT ASKS FOR PERMISSIONS
    public static void verifyStoragePermissions(Activity activity) {
        // Check if we have write permission
        int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);

        if (permission != PackageManager.PERMISSION_GRANTED) {
            // We don't have permission so prompt the user
            ActivityCompat.requestPermissions(
                    activity,
                    PERMISSIONS_STORAGE,
                    REQUEST_EXTERNAL_STORAGE
            );
        }
    }

  @Override //ON REQUEST PERMISSION RESULT, 
//I ACCEPTED THE PERMISSION, THE CODE HERE WAS EXECUTED AS IT SHOULD
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {

            case 1: {
                Log.d(TAG,"THIS IS FOR THE WRITE/READ PERMISSIONS");
                Log.d(TAG,grantResults.toString());
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.d(TAG,"[Persmission accepted for writing/reading]");


                    // permission was granted, yay! Do the
                    // camera related task you need to do.
                } else {
                    Log.d(TAG,"[Permission denied]");
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }

            }

            // other 'case' lines to check for other
            // permissions this app might request.
        }
    }

 //THE METHOD WHERE THE ERROR HAPPENS
 public String saveImage(Bitmap myBitmap) {

        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes);

        File wallpaperDirectory = new File(
                Environment.getExternalStorageDirectory() + "TEST_APP_PHOTO_FOLDER");

        // have the object build the directory structure, if needed.
        if (!wallpaperDirectory.exists()) {

            wallpaperDirectory.mkdirs();
        }

        try {

            File f = new File(wallpaperDirectory + "testfile.jpg");

            f.mkdirs();
          f.createNewFile(); // <--- STACK TRACE POINTS HERE

            FileOutputStream fo = new FileOutputStream(f);
..
..
..

The error happens in the saveImage() method. I have comments explaining where it happens. I have tried the method with the f.mkdirs() and without it, does not work either way. Permission denied both times.

STACK TRACE

java.io.IOException: Permission denied
        at java.io.UnixFileSystem.createFileExclusively0(Native Method)
        at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:281)
        at java.io.File.createNewFile(File.java:1000)
        at car.andrej.tradingapp.ProfileActivity.ProfileActivity.saveImage(ProfileActivity.java:263)
        at car.andrej.tradingapp.ProfileActivity.ProfileActivity.onActivityResult(ProfileActivity.java:220)
        at android.app.Activity.dispatchActivityResult(Activity.java:7556)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4487)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4534)
        at android.app.ActivityThread.-wrap20(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1752)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6944)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

In the manifest :

 <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

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

What am i missing?...

Upvotes: 4

Views: 583

Answers (1)

Mike M.
Mike M.

Reputation: 39201

This isn't an Android permissions issue. Rather, the Exception is due to Linux permissions, though inadvertently.

In instantiating the Files used in saveImage(), you're concatenating the name of the new file/directory to Environment.getExternalStorageDirectory(); e.g., for wallpaperDirectory:

new File(Environment.getExternalStorageDirectory() + "TEST_APP_PHOTO_FOLDER")

This is implicitly calling toString() on Environment.getExternalStorageDirectory() and directly appending the name to it without the necessary path separator in between, so you end up with a full name that's something like /storage/emulated/0TEST_APP_PHOTO_FOLDER. This refers to a file in the parent of the external storage directory, and you don't have write access there, thus the Exception.

Simply change your File instantiations to use the constructor that takes separate File and String arguments; the first for the parent directory, and the second for the name. Basically, change the plus sign to a comma. For example:

new File(Environment.getExternalStorageDirectory(), "TEST_APP_PHOTO_FOLDER")

Upvotes: 3

Related Questions