Asdemuertes
Asdemuertes

Reputation: 323

Android write on external Storage

I'm trying to write some drawables in my extornal storage with this code :

Bitmap bm = BitmapFactory.decodeResource( getResources(), R.drawable.paco);

        File file = new File( Environment.getExternalStorageDirectory(), "paco.png");
        FileOutputStream outStream = null;

        try {
        FileOutputStream out = new FileOutputStream(file);
        bm.compress(Bitmap.CompressFormat.PNG, 90, out);
        out.flush();
        out.close();
            Log.d("XXXXX","voy a cerrar");
        } catch (Exception e) {
           Log.e("XXXXX","eeeee", e);
        }

But I keep getting this error:

28476-28476/com.example.usuari.myapplication3 E/XXXXX: eeeee java.io.FileNotFoundException: /storage/emulated/0/paco.png: open failed: EACCES (Permission denied) at libcore.io.IoBridge.open(IoBridge.java:452) at java.io.FileOutputStream.(FileOutputStream.java:87) at java.io.FileOutputStream.(FileOutputStream.java:72) at com.example.usuari.myapplication3.MainActivity.iniciarDrawables(MainActivity.java:276) at com.example.usuari.myapplication3.MainActivity.onCreate(MainActivity.java:90) at android.app.Activity.performCreate(Activity.java:6876) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1135) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3207) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3350) at android.app.ActivityThread.access$1100(ActivityThread.java:222) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:158) at android.app.ActivityThread.main(ActivityThread.java:7229) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied) at libcore.io.Posix.open(Native Method) at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186) at libcore.io.IoBridge.open(IoBridge.java:438) at java.io.FileOutputStream.(FileOutputStream.java:87)  at java.io.FileOutputStream.(FileOutputStream.java:72)  at com.example.usuari.myapplication3.MainActivity.iniciarDrawables(MainActivity.java:276)  at com.example.usuari.myapplication3.MainActivity.onCreate(MainActivity.java:90)  at android.app.Activity.performCreate(Activity.java:6876)  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1135)  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3207)  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3350)  at android.app.ActivityThread.access$1100(ActivityThread.java:222)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:158)  at android.app.ActivityThread.main(ActivityThread.java:7229)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

I have the permission entry in my manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.usuari.myapplication3">

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

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

...

Edit: I'm working with sdk 23

Upvotes: 0

Views: 862

Answers (3)

Eugene Chumak
Eugene Chumak

Reputation: 3192

At first, check that your storage is ready:

if (Environment.getExternalStorageState(file) != Environment.MEDIA_MOUNTED) {
    // your storage is not ready for work, do something with this
}

Secondly, as far, as I remember, starting from Kit-Kat you can not write to the root of external storage. It is only allowed to write to application specific folder on the storage. To get this folder, use

Environment.getExternalStoragePublicDirectory(directoryType);

What about directoryType, check method`s documentation, you, probably, want to use Environment.DIRECTORY_PICTURES.

Try this.

Upvotes: 1

rafsanahmad007
rafsanahmad007

Reputation: 23881

Android Sdk >=23 needs runtime permission from user. Only adding permission to manifest will not work.

Try this code:

 if(isPermissionGranted()){
      //open file
    }
 public  boolean isPermissionGranted() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                == PackageManager.PERMISSION_GRANTED) {
            Log.v("TAG","Permission is granted");
            return true;
        } else {

            Log.v("TAG","Permission is revoked");
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
            return false;
        }
    }
    else { //permission is automatically granted on sdk<23 upon installation
        Log.v("TAG","Permission is granted");
        return true;
    }
}

catch the permission result in:

 @Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {

        case 0: {

            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(getApplicationContext(), "Permission granted", Toast.LENGTH_SHORT).show();
                //call your method open file
            } else {
                Toast.makeText(getApplicationContext(), "Permission denied", Toast.LENGTH_SHORT).show();
            }
            return;
        }
    }
 }

Upvotes: 1

Mohammed Bakr Sikal
Mohammed Bakr Sikal

Reputation: 357

If you are on API 23+, you have to request the permissions at RunTime (although they are already present in the manifest file).

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)
        != PackageManager.PERMISSION_GRANTED) {

    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.WRITE_EXTERNAL_STORAGE)) {

        // Show an explanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.

    } else {

        // No explanation needed, we can request the permission.

        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
}

Upvotes: 1

Related Questions