READ_EXTERNAL_STORAGE permission for Android
Solution 1
You have two solutions for your problem. The quick one is to lower targetApi to 22 (build.gradle file). Second is to use new and wonderful ask-for-permission model:
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (shouldShowRequestPermissionRationale(
Manifest.permission.READ_EXTERNAL_STORAGE)) {
// Explain to the user why we need to read the contacts
}
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
// MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
// app-defined int constant that should be quite unique
return;
}
Sniplet found here: https://developer.android.com/training/permissions/requesting.html
Solutions 2: If it does not work try this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_PERMISSION);
return;
}
and then in callback
@Override
public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted.
} else {
// User refused to grant permission.
}
}
}
that is from comments. thanks
Solution 2
You have to ask for the permission at run time:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_PERMISSION);
dialog.dismiss();
return;
}
And in the callback below you can access the storage without a problem.
@Override
public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted.
} else {
// User refused to grant permission.
}
}
}
Solution 3
Step1: add permission on android manifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Step2: onCreate() method
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_MEDIA);
} else {
readDataExternal();
}
Step3: override onRequestPermissionsResult method to get callback
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_MEDIA:
if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
readDataExternal();
}
break;
default:
break;
}
}
Note: readDataExternal() is method to get data from external storage.
Thanks.
Solution 4
I also had a similar error log and here's what I did-
-
In onCreate method we request a Dialog Box for checking permissions
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1);
-
Method to check for the result
@Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case 1: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission granted and now can proceed mymethod(); //a sample method called } else { // permission denied, boo! Disable the // functionality that depends on this permission. Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show(); } return; } // add other cases for more permissions } }
The official documentation to Requesting Runtime Permissions
Solution 5
In 2021 I am facing this issue So I will solve this problem using the manifest file I add one tag inside application:
<application
android:requestLegacyExternalStorage="true"
/>
NOTE: This only work until Android 10, see more information here
Related videos on Youtube
Slim Sim
Updated on May 05, 2022Comments
-
Slim Sim about 2 years
I'm trying to access media files (music) on the users device to play them; an easy "hello world"-music player app.
I've followed some tutorials and they basically give the same code. But it won't work; it keeps crashing and telling me:
error..... Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/audio/media from pid=27696, uid=10059 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission() ....
Now, this is my manifest file:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="slimsimapps.troff" > <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
This is my Java-method:
public void initialize() { ContentResolver contentResolver = getContentResolver(); Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; Cursor cursor = contentResolver.query(uri, null, null, null, null); if (cursor == null) { // query failed, handle error. } else if (!cursor.moveToFirst()) { // no media on the device } else { do { addSongToXML(cursor); } while (cursor.moveToNext()); } }
I have tried:
To put this at different places in the manifest file:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE”/>
To add android:maxSdkVersion at Read external storage premission:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="21" />
To put this in the manifest / application / activity-tag:
android:exported=“true”
To put grantUriPremission between uri and cursro in the javamethod:
grantUriPermission(null, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
To use this, it won't crash, but the cursor becomes null:
uri = MediaStore.Audio.Media.getContentUri("EXTERNAL_CONTENT_URI”);
To use INTERNAL content uri, this works as expected, but it only gives "OS-sounds" such as shutter-sound, low-battery-sound, button-click and such:
uri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI;
Pleas help, this should not be a hard problem i know, but i feel like such a beginner!
I have read and tried (or considered them to be not applicable for my problem):
- Android READ_EXTERNAL_STORAGE permission not working
- Require permission only for older android versions: maxSdkVersion does not work?
- Get filename and path from URI from mediastore
- Android KitKat securityException when trying to read from MediaStore
- Android: java.lang.SecurityException: Permission Denial: start Intent
Stack trace:
09-08 06:59:36.619 2009-2009/slimsimapps.troff D/AndroidRuntime﹕ Shutting down VM --------- beginning of crash 09-08 06:59:36.619 2009-2009/slimsimapps.troff E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: slimsimapps.troff, PID: 2009 java.lang.IllegalStateException: Could not execute method for android:onClick at android.view.View$DeclaredOnClickListener.onClick(View.java:4452) at android.view.View.performClick(View.java:5198) at android.view.View$PerformClick.run(View.java:21147) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at android.view.View$DeclaredOnClickListener.onClick(View.java:4447) at android.view.View.performClick(View.java:5198) at android.view.View$PerformClick.run(View.java:21147) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/audio/media from pid=2009, uid=10059 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission() at android.os.Parcel.readException(Parcel.java:1599) at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183) at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135) at android.content.ContentProviderProxy.query(ContentProviderNative.java:421) at android.content.ContentResolver.query(ContentResolver.java:491) at android.content.ContentResolver.query(ContentResolver.java:434) at slimsimapps.troff.MainActivity.initialize(MainActivity.java:106) at slimsimapps.troff.MainActivity.InitializeExternal(MainActivity.java:80) at java.lang.reflect.Method.invoke(Native Method) at android.view.View$DeclaredOnClickListener.onClick(View.java:4447) at android.view.View.performClick(View.java:5198) at android.view.View$PerformClick.run(View.java:21147) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) --------- beginning of system
-
Sunil Sunny over 8 yearsStrange that error is shown when you have not given this line in manifest <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> are you trying to read some files which is protected by some other apps?
-
Sharp Edge over 8 yearsOn which api level are you trying this ?
-
Sunil Sunny over 8 yearsDid you tried cleaning the project. ?
-
Slim Sim over 8 years@sunilsunny I'm not trying to read som files that are protected, not that I know of anyway, just a simple media player. Yes, I have tried to clean it, i have tried to restart computer, I have tried to generate a signed APK and publish it to google Play and access it as a tester, with no luck....
-
Slim Sim over 8 years@SharpEdge ; My AVD is the standard Nexus 5, api 23. My module gradle has: compileSdkVersion 23 buildToolsVersion "23.0.0" minSdkVersion 14 targetSdkVersion 23 So i would say 23.
-
k3b over 8 yearscan you open your specific audio with any other media player? is the file drm protected? or is located in a protected directory where only super-user has access to?
-
Slim Sim over 8 years@k3b I don't have any other audio on my AVD, but I would like for my app to say, nrSongs=0, instead of crashing. On my mobile device i have songs, which I can open with both Google Play Music, and another music player I downloaded from the play store. so, Yes - I Can. "Is the file drm protected?" - I don't know, I just want to access all the music files that I'm allowed to access... like a music player... "Is it located in a protected directory..." same anser as before. Note; I'm not including the audio as part of the app, I want to play the audio from the users media library.
-
Slim Sim over 8 yearsThanks, I have tried something similar before, but I tried your code and it crashes on "cursor = managedQuery(allsongsuri, STAR, selection, null, null);", same error as before. By the way; managedQuery is deprecated, but it still crashes if i change it to "contentResolver.query", which have the same input parameters...
-
Slim Sim over 8 yearsThanks, I tried your suggestion but it crashed on the same spot... I'm using a Mac, can that be a problem?
-
Derek Fung over 8 yearsupdated, try to remove
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
and try? It may create strange behaviour because your app request for an permission not allowed -
Rajan Bhavsar over 8 yearsHi I am able to get All sdcadr Songs using above code. with Android Version 4.2.2 Device and also able to with Version 5.0.2. In which You are trying. What Error you got please describe with Android Version
-
Slim Sim over 8 yearsthanks, i tried to remove that permission, but it crashes at the same spot with the same error...
-
Slim Sim over 8 yearsI have updated the question with the stack-trace, hope that helps. What do you mean with Android Version? (I'm using apk 23)
-
Rajan Bhavsar over 8 yearsOk Let me Give Full Source code and Check Out that again.
-
Slim Sim over 8 yearsif you want to test for yourself, download the zip here: drive.google.com/open?id=0B2AV8VRk9HUeVzFXSWVRZU9TRUk when you run it, press the left initialize-button, to generate the crach.
-
Slim Sim over 8 yearsYes, of course! The new permission model Google introduced with the latest Android! Thank you, I will test this as soon as possible and mark it correct if it works! (and i was beginning to think this was forgotten!)
-
maclir about 8 yearsThe permission that is being requested should be
READ_EXTERNAL_STORAGE
. Like in this answer. -
George Kagan almost 8 yearsWorked for me using Cordova, by setting only the max SDK version in AndroidManifest.xml to 22 (instead of 23)
-
Renascienza over 7 yearsI think you misplaced the needed permission here: is READ_EXTERNAL_STORAGE.
-
Renascienza over 7 yearsswap != PackageManager.READ_EXTERNAL_STORAGE for != PackageManager.PERMISSION_GRANTED
-
piotrpo over 7 years@Renascienza, yes you're right. Someone edited this answer in wrong way.
-
TheQ about 7 yearswhere does checkSelfPermissions() come from, im getting a red line error here?
-
Solo almost 7 yearsWhat is MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE ?
-
piotrpo almost 7 years@Solo Just an int constant used to identify permission granted event in the callback. This value is returned as a param to onRequestPermissionResult(...) method.
-
Mahdi H almost 7 yearsi used it and it worked perfectly does it work on all android devices ?
-
Ateş Danış over 2 yearsrequestLegacyExternalStorage *typo