web-dev-qa-db-fra.com

Erreur de permission d'utilisateur Android M - LIRE et WRITE

Je viens de commencer avec Android M et je ne parviens pas à accéder au stockage externe. Je reçois l'erreur suivante

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

J'ajoute une permission d'utilisateur dans le manifeste, comme 

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

et mon fichier de construction est avec les paramètres suivants:

compileSdkVersion 23
buildToolsVersion "22.0.1"

minSdkVersion 16
targetSdkVersion 23

Comment lire et écrire à partir d'un stockage externe sous Android M? 

12
Kushal Sharma

Lecture de la documentation . Je dois demander l'autorisation à l'utilisateur au moment de l'exécution. Exemple de code: 

Ajoutez l'autorisation au manifeste Android comme nous le faisions auparavant: 

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

Vérifiez si l'utilisateur a déjà accordé l'autorisation. Si oui, ignorez la demande d'autorisation et poursuivez votre flux de travail, sinon demandez à l'utilisateur l'autorisation:

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
}

Maintenant, pour vérifier si l'utilisateur a accordé ou refusé l'autorisation @OverrideOnRequestPermissionResult pour obtenir un rappel:

@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;
        }
    }
}

Je ne pouvais pas lire le stockage externe uniquement en demandant à WRITE permission, donc je devais demander Manifest.permission.READ_EXTERNAL_STORAGE aussi.


De même, si vous souhaitez cibler les versions inférieures à l'API 23, cochez la case Build VERSION au moment de l'exécution avec l'instruction IF et ne demander des autorisations que si VERSION est égal ou supérieur à Android M.

21
Kushal Sharma

Si vous recherchez un moyen de gérer n'importe quelle version d'Android (vous compilez pour M, mais certains appareils peuvent utiliser d'autres versions), il existe une version de compatibilité.

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

En ce qui concerne la réponse choisie:

Settings.System.canWrite(this) et WRITE_EXTERNAL_STORAGE sont deux choses très différentes! Devrait être:

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

Je me débattais avec l'autorisation WRITE_EXTERNAL_STORAGE: après l'avoir demandée, la boîte de dialogue ne s'est pas affichée et a immédiatement renvoyé DENIED.

Le problème était dans l'une des bibliothèques incluses. Il contenait la même déclaration d'autorisation dans son AndroidManifest.xml, mais avec maxSdkVersion="22". La déclaration dans le fichier manifeste de l'application a été remplacée par la bibliothèque.

Pour remplacer l'autorisation de la bibliothèque, j'ai utilisé ce qui suit:

  <uses-permission
    Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"
    tools:node="remove"
    tools:selector="com.example.lib" />

J'espère que cela pourrait être utile.

1
ntoskrnl