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?
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 @Override
OnRequestPermissionResult
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
.
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.
}
}
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()
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.