Android M User Permission Error - READ and WRITE

六眼飞鱼酱① 提交于 2019-11-27 05:54:28

问题


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?


回答1:


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 above Android M.




回答2:


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.
        }
    }



回答3:


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()



回答4:


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.




回答5:


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://github.com/kayvannj/PermissionUtil



来源:https://stackoverflow.com/questions/32175770/android-m-user-permission-error-read-and-write

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!