Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MediaStore.Images.Media.insertImage throwing permission denial on some devices

I have problem with line of code:

String path = MediaStore.Images.Media.insertImage(activity.getContentResolver(), bitmap, "feedback", null);

Activity is not null, bitmap is not null.

I get error:

0-22 11:23:59.644 29514-29527/? E/DatabaseUtils: Writing exception to parcel
10-22 11:23:59.644 29514-29527/? E/DatabaseUtils: java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=1380, uid=10136 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()
10-22 11:23:59.644 29514-29527/? E/DatabaseUtils:     at android.content.ContentProvider.enforceWritePermissionInner(ContentProvider.java:679)
10-22 11:23:59.644 29514-29527/? E/DatabaseUtils:     at android.content.ContentProvider$Transport.enforceWritePermission(ContentProvider.java:494)
10-22 11:23:59.644 29514-29527/? E/DatabaseUtils:     at android.content.ContentProvider$Transport.insert(ContentProvider.java:258)
10-22 11:23:59.644 29514-29527/? E/DatabaseUtils:     at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:163)
10-22 11:23:59.644 29514-29527/? E/DatabaseUtils:     at android.os.Binder.execTransact(Binder.java:453)
10-22 11:23:59.645 1380-1467/? E/MediaStore: Failed to insert image
10-22 11:23:59.645 1380-1467/? E/MediaStore: java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=1380, uid=10136 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()
10-22 11:23:59.645 1380-1467/? E/MediaStore:     at android.os.Parcel.readException(Parcel.java:1599)
10-22 11:23:59.645 1380-1467/? E/MediaStore:     at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
10-22 11:23:59.645 1380-1467/? E/MediaStore:     at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
10-22 11:23:59.645 1380-1467/? E/MediaStore:     at android.content.ContentProviderProxy.insert(ContentProviderNative.java:476)
10-22 11:23:59.645 1380-1467/? E/MediaStore:     at android.content.ContentResolver.insert(ContentResolver.java:1231)
10-22 11:23:59.645 1380-1467/? E/MediaStore:     at android.provider.MediaStore$Images$Media.insertImage(MediaStore.java:962)
10-22 11:23:59.645 1380-1467/? E/MediaStore:     at com.azimo.sendmoney.a.utils.Screenshot$1.call(Screenshot.java:58)
10-22 11:23:59.645 1380-1467/? E/MediaStore:     at com.azimo.sendmoney.a.utils.Screenshot$1.call(Screenshot.java:51)
10-22 11:23:59.645 1380-1467/? E/MediaStore:     at rx.Observable.unsafeSubscribe(Observable.java:7531)
10-22 11:23:59.645 1380-1467/? E/MediaStore:     at rx.internal.operators.OperatorSubscribeOn$1$1.call(OperatorSubscribeOn.java:62)
10-22 11:23:59.645 1380-1467/? E/MediaStore:     at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
10-22 11:23:59.645 1380-1467/? E/MediaStore:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
10-22 11:23:59.645 1380-1467/? E/MediaStore:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
10-22 11:23:59.645 1380-1467/? E/MediaStore:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
10-22 11:23:59.645 1380-1467/? E/MediaStore:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
10-22 11:23:59.645 1380-1467/? E/MediaStore:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
10-22 11:23:59.645 1380-1467/? E/MediaStore:     at java.lang.Thread.run(Thread.java:818)

I have permissions in my manifest:

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

Works on 5.1.1 Nexus 4. Doesn't work on 6.0 Nexus 6.

Do you have any idea how could I fix it? Maybe adding some permissions programatically?

like image 477
F1sher Avatar asked Oct 22 '15 09:10

F1sher


1 Answers

Quoting developers.android.com:

Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. This approach streamlines the app install process, since the user does not need to grant permissions when they install or update the app. It also gives the user more control over the app's functionality; for example, a user could choose to give a camera app access to the camera but not to the device location. The user can revoke the permissions at any time, by going to the app's Settings screen.

System permissions are divided into two categories, normal and dangerous:

  • Normal permissions do not directly risk the user's privacy. If your app lists a normal permission in its manifest, the system grants the permission automatically.

  • Dangerous permissions can give the app access to the user's confidential data. If your app lists a normal permission in its manifest, the system grants the permission automatically. If you list a dangerous permission, the user has to explicitly give approval to your app.

READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE are in the Dangerous category, for this reason when targetSdkVersion is 23 or higher you need to request the permission directly to the user when the app is running.

Nothing has changed for device with API level lower than 23, this is why you don't have any issue with Nexus 4.

You can find more information on how to check and request a permission here: https://developer.android.com/training/permissions/requesting.html

like image 56
Mattia Maestrini Avatar answered Oct 21 '22 05:10

Mattia Maestrini