Search code examples
androidextern

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


Solution

  • 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;
            }
        }
     }