I just started off with android M and I am unable to access the external storage. I get the following error
Caused by: java.lang.SecurityException: Permission Denial: reading
com.android.providers.media.MediaProvider uri
content://media/external/images/media from pid=15355, uid=10053 requires
android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
I am adding user-permission in manifest like
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
and my build file is with following settings :
compileSdkVersion 23
buildToolsVersion "22.0.1"
minSdkVersion 16
targetSdkVersion 23
How to read and write from external storage in android M?
Reading from the documentation. I have to ask user for permission at runtime. Code example :
Add permission to android manifest like we used to do earlier :
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Check if the user has already granted the permission. If yes, skip asking for permission and continue with your work flow else ask user for permission :
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.System.canWrite(this)) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE}, 2909);
} else {
// continue with your code
}
} else {
// continue with your code
}
Now to check if the user granted the permission or denied it @Override
OnRequestPermissionResult
to get a callback :
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 2909: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.e("Permission", "Granted");
} else {
Log.e("Permission", "Denied");
}
return;
}
}
}
I was not able to READ external storage only by asking WRITE permission, so i had to request for
Manifest.permission.READ_EXTERNAL_STORAGE
as well.
Also if you want to target versions below api 23, check the Build VERSION at runtime with
IF
statement and ask for permissions only if VERSION is equal or aboveAndroid M
.
In case you are looking for a way to handle in any android version (you are compiling for M, but some devices can be using other versions) there is a compatibility version.
if (ContextCompat.checkSelfPermission(CreatePlayerActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(CreatePlayerActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE)) {
// Show an expanation 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(CreatePlayerActivity.this,
new String[]{Manifest.permission.READ_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.
}
}
In regards to the selected answer:
Settings.System.canWrite(this)
and WRITE_EXTERNAL_STORAGE
are two very different things! Should be:
boolean needsRead = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED;
boolean needsWrite = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED;
if (needsRead || needsWrite)
requestStoragePermission()
I was struggling with WRITE_EXTERNAL_STORAGE
permission: after I requested it, the dialog didn't show up and immediately returned DENIED
.
The problem was in one of the included libraries. It contained the same permission declaration in its AndroidManifest.xml
, but with maxSdkVersion="22"
. The declaration in application's manifest file was overridden by the library.
To override permission from the library I used the following:
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:node="remove"
tools:selector="com.example.lib" />
I hope this might be helpful.
I used this utility on github. It works with with both API 22 and 23. Adding runtime permissions is not hard but having to seperate your code and move the methods around to capture callbacks is a little pain. This library provides a chained api to do all you need to do for supporting runtime permissions.
来源:https://stackoverflow.com/questions/32175770/android-m-user-permission-error-read-and-write