0

I try to save bitmap image on sdcard but show permission exception.

sdcard permission

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
java.io.FileNotFoundException: /storage/emulated/0/Horoscope/IMG_1569837709260.png (Permission denied)

my save bitmap method

public static void saveImage(Bitmap finalBitmap, Activity activity) {
        File myDir = new File(Environment.getExternalStorageDirectory().getPath() + "/Horoscope");
        myDir.mkdirs();
        String fname = "IMG_" + System.currentTimeMillis() + ".png";
        File file = new File(myDir, fname);

        try (FileOutputStream out = new FileOutputStream(file)) {
            finalBitmap.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
            MediaStore.Images.Media.insertImage(activity.getContentResolver(), file.getPath(), fname, "description");
            Toast.makeText(activity, "Saved.", Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

error exception

java.io.FileNotFoundException: /storage/emulated/0/Horoscope/IMG_1569837709260.png (Permission denied)
            at java.io.FileOutputStream.open0(Native Method)
            at java.io.FileOutputStream.open(FileOutputStream.java:287)
            at java.io.FileOutputStream.<init>(FileOutputStream.java:223)
            at java.io.FileOutputStream.<init>(FileOutputStream.java:171)
            at com.example.opencv.utils.Constant.saveImage(Constant.java:378)
            at com.example.opencv.activity.ForeignerMakerResultActivity$3.onClick(ForeignerMakerResultActivity.java:106)
            at android.view.View.performClick(View.java:6319)
            at android.view.View$PerformClick.run(View.java:24955)
            at android.os.Handler.handleCallback(Handler.java:790)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:192)
            at android.app.ActivityThread.main(ActivityThread.java:6760)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:826)
Anice Jahanjoo
  • 7,088
  • 3
  • 20
  • 29
Ashish Virani
  • 182
  • 1
  • 15
  • Have you requested the permissions? It seems like you have just written the permission in but you have not requested the permissions. Just request the permission and after the user grants the permissions save your bitmap – Kartik Sep 30 '19 at 10:17
  • You need to request "runtime permission" for dangerous permission such as SD card. Please see the link I commented. – Stanley Ko Sep 30 '19 at 10:18
  • You can use below repo for runtime permission using annotations. https://github.com/permissions-dispatcher/PermissionsDispatcher – Nikunj Patel Sep 30 '19 at 10:20

3 Answers3

3

You must check and grant storage permission at tun time.

Along with that you need add below code for SDK version >23

Extend Application class and inside onCreate() method put below code

StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
    StrictMode.setVmPolicy(builder.build());
    if (Build.VERSION.SDK_INT > 23) {
        builder.detectFileUriExposure();
    }

In Manifest.xml set android:name value to your application class.

It would be like,

<application
    android:name="com.gym.client.WebURLApplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:theme="@style/AppTheme">
</application>
Exigente05
  • 2,161
  • 3
  • 22
  • 42
1

You have to request permission on Activity

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

You also should check the mkdirs result as well to catch error like this

 if (myDir.mkdirs()) {}
ChickenSoups
  • 937
  • 8
  • 18
1

Since WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE are critical permissions, You have to check the permissions in runtime after you declared them in manifest.

if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)
        == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE)
        == PackageManager.PERMISSION_GRANTED) {
    // Permission is granted
}
else {
    //Permission is not granted so you have to request it
    ActivityCompat.requestPermissions(activity,
                new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE},
                MY_PERMISSIONS_REQUEST);
}
Saman Salehi
  • 1,995
  • 1
  • 22
  • 36