Erreur de permission de stockage dans Marshmallow

Dans Lollipop, la fonctionnalité de téléchargement fonctionne bien dans mon application, mais lorsque je mets à niveau vers Marshmallow, mon application plante et donne cette erreur lorsque j’essaie de télécharger depuis Internet sur la carte SD:

Neither user nor current process has android.permission.WRITE_EXTERNAL_STORAGE 

Il se plaint de cette ligne de code:

 DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); manager.enqueue(request); 

J’ai les permissions dans le manifeste en dehors de l’application:

    

J’ai nettoyé et reconstruit le projet, mais il se bloque toujours.

Vous devriez vérifier si l’utilisateur a accordé la permission de stockage externe en utilisant:

 if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { Log.v(TAG,"Permission is granted"); //File write logic here return true; } 

Sinon, vous devez demander à l’utilisateur d’accorder une autorisation à votre application:

 ActivityCompat.requestPermissions(this, new Ssortingng[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE); 

Bien sûr, ce ne sont que pour les dispositifs de guimauve, vous devez donc vérifier si votre application s’exécute sur Marshmallow:

  if (Build.VERSION.SDK_INT >= 23) { //do your check here } 

Assurez-vous également que votre activité implémente OnRequestPermissionResult

La permission entière ressemble à ceci:

 public boolean isStoragePermissionGranted() { if (Build.VERSION.SDK_INT >= 23) { if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { Log.v(TAG,"Permission is granted"); return true; } else { Log.v(TAG,"Permission is revoked"); ActivityCompat.requestPermissions(this, new Ssortingng[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); return false; } } else { //permission is automatically granted on sdk<23 upon installation Log.v(TAG,"Permission is granted"); return true; } } 

Rappel du résultat de l'autorisation:

 @Override public void onRequestPermissionsResult(int requestCode, Ssortingng[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if(grantResults[0]== PackageManager.PERMISSION_GRANTED){ Log.v(TAG,"Permission: "+permissions[0]+ "was "+grantResults[0]); //resume tasks needing this permission } } 

Le système d’autorisation d’Android est l’un des problèmes de sécurité les plus importants depuis que ces permissions sont demandées au moment de l’installation. Une fois installée, l’application pourra accéder à toutes les choses accordées sans accusé de réception de la part de l’application.

Android 6.0 Marshmallow introduit l’une des plus grandes modifications apscopes au modèle d’permissions avec l’ajout d’permissions d’exécution, un nouveau modèle d’autorisation qui remplace le modèle d’permissions d’installation existant lorsque vous ciblez l’API 23 et l’application s’exécute sur un périphérique Android 6.0+

La courtoisie va à la demande d’permissions à l’exécution .

Exemple

Déclarez ceci comme global

 private static final int PERMISSION_REQUEST_CODE = 1; 

Ajoutez ceci dans votre section onCreate()

Après setContentView (R.layout.your_xml);

  if (Build.VERSION.SDK_INT >= 23) { if (checkPermission()) { // Code for above or equal 23 API Oriented Device // Your Permission granted already .Do next code } else { requestPermission(); // Code for permission } } else { // Code for Below 23 API Oriented Device // Do next code } 

Ajouter maintenant checkPermission () et requestPermission ()

  private boolean checkPermission() { int result = ContextCompat.checkSelfPermission(Your_Activity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE); if (result == PackageManager.PERMISSION_GRANTED) { return true; } else { return false; } } private void requestPermission() { if (ActivityCompat.shouldShowRequestPermissionRationale(Your_Activity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) { Toast.makeText(Your_Activity.this, "Write External Storage permission allows us to do store images. Please allow this permission in App Settings.", Toast.LENGTH_LONG).show(); } else { ActivityCompat.requestPermissions(Your_Activity.this, new Ssortingng[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE); } } @Override public void onRequestPermissionsResult(int requestCode, Ssortingng permissions[], int[] grantResults) { switch (requestCode) { case PERMISSION_REQUEST_CODE: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Log.e("value", "Permission Granted, Now you can use local drive ."); } else { Log.e("value", "Permission Denied, You cannot use local drive ."); } break; } } 

FYI

onRequestPermissionsResult

Cette interface est le contrat pour recevoir les résultats des demandes d’autorisation.

A moins qu’il y ait une exigence précise d’écriture sur le stockage externe, vous pouvez toujours choisir d’enregistrer les fichiers dans le répertoire de l’application. Dans mon cas, j’ai dû enregistrer des fichiers et après avoir perdu 2 à 3 jours, j’ai découvert si je changeais le chemin de stockage à partir de

 Environment.getExternalStorageDirectory() 

à

 getApplicationContext().getFilesDir().getPath() //which returns the internal app files directory path 

cela fonctionne comme du charme sur tous les appareils. En effet, pour l’écriture sur le stockage externe, vous avez besoin d’permissions supplémentaires, mais l’écriture dans le répertoire des applications internes est simple.

Vérifier plusieurs permissions au niveau de l’API 23 Etape 1:

  Ssortingng[] permissions = new Ssortingng[]{ Manifest.permission.INTERNET, Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.VIBRATE, Manifest.permission.RECORD_AUDIO, }; 

Étape 2:

  private boolean checkPermissions() { int result; List listPermissionsNeeded = new ArrayList<>(); for (String p : permissions) { result = ContextCompat.checkSelfPermission(this, p); if (result != PackageManager.PERMISSION_GRANTED) { listPermissionsNeeded.add(p); } } if (!listPermissionsNeeded.isEmpty()) { ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), 100); return false; } return true; } 

Étape 3:

  @Override public void onRequestPermissionsResult(int requestCode, Ssortingng permissions[], int[] grantResults) { if (requestCode == 100) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // do something } return; } } 

Étape 4: dans onCréer une activité checkPermissions ();

vous devez utiliser la permission d’exécution dans marshmallow https://developer.android.com/training/permissions/requesting.html

vous pouvez archiver les infos de l’application -> permission

est votre application obtenir la permission pour écrire le stockage externe ou non

Semble que l’utilisateur a refusé la permission et l’application tente d’écrire sur le disque externe, provoquant une erreur.

 @Override public void onRequestPermissionsResult(int requestCode, Ssortingng permissions[], int[] grantResults) { switch (requestCode) { case MY_PERMISSIONS_REQUEST_READ_CONTACTS: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted, yay! Do the // contacts-related task you need to do. } else { // permission denied, boo! Disable the // functionality that depends on this permission. } return; } // other 'case' lines to check for other // permissions this app might request } } 

Vérifiez https://developer.android.com/training/permissions/requesting.html

Cette vidéo vous donnera une meilleure idée sur UX, en gérant les permissions d’exécution. https://www.youtube.com/watch?v=iZqDdvhTZj0

À partir de la version de guimauve, les développeurs doivent demander à l’utilisateur des permissions d’exécution. Permettez-moi de vous donner un processus complet pour demander des permissions d’exécution.

J’utilise la référence d’ici: permissions d’exécution guimauve android .

Commencez par créer une méthode qui vérifie si toutes les permissions sont données ou non

 private boolean checkAndRequestPermissions() { int camerapermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA); int writepermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE); int permissionLocation = ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION); int permissionRecordAudio = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO); List listPermissionsNeeded = new ArrayList<>(); if (camerapermission != PackageManager.PERMISSION_GRANTED) { listPermissionsNeeded.add(Manifest.permission.CAMERA); } if (writepermission != PackageManager.PERMISSION_GRANTED) { listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); } if (permissionLocation != PackageManager.PERMISSION_GRANTED) { listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION); } if (permissionRecordAudio != PackageManager.PERMISSION_GRANTED) { listPermissionsNeeded.add(Manifest.permission.RECORD_AUDIO); } if (!listPermissionsNeeded.isEmpty()) { ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS); return false; } return true; } 

Maintenant, voici le code qui est exécuté après la méthode ci-dessus. Nous allons remplacer la méthode onRequestPermissionsResult() :

  @Override public void onRequestPermissionsResult(int requestCode, Ssortingng permissions[], int[] grantResults) { Log.d(TAG, "Permission callback called-------"); switch (requestCode) { case REQUEST_ID_MULTIPLE_PERMISSIONS: { Map perms = new HashMap<>(); // Initialize the map with both permissions perms.put(Manifest.permission.CAMERA, PackageManager.PERMISSION_GRANTED); perms.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED); perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED); perms.put(Manifest.permission.RECORD_AUDIO, PackageManager.PERMISSION_GRANTED); // Fill with actual results from user if (grantResults.length > 0) { for (int i = 0; i < permissions.length; i++) perms.put(permissions[i], grantResults[i]); // Check for both permissions if (perms.get(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) { Log.d(TAG, "sms & location services permission granted"); // process the normal flow Intent i = new Intent(MainActivity.this, WelcomeActivity.class); startActivity(i); finish(); //else any one or both the permissions are not granted } else { Log.d(TAG, "Some permissions are not granted ask again "); //permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission // // shouldShowRequestPermissionRationale will return true //show the dialog or snackbar saying its necessary and try again otherwise proceed with setup. if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) { showDialogOK("Service Permissions are required for this app", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { switch (which) { case DialogInterface.BUTTON_POSITIVE: checkAndRequestPermissions(); break; case DialogInterface.BUTTON_NEGATIVE: // proceed with logic by disabling the related features or quit the app. finish(); break; } } }); } //permission is denied (and never ask again is checked) //shouldShowRequestPermissionRationale will return false else { explain("You need to give some mandatory permissions to continue. Do you want to go to app settings?"); // //proceed with logic by disabling the related features or quit the app. } } } } } } 

Si l'utilisateur clique sur l'option Refuser, la méthode showDialogOK() sera utilisée pour afficher la boîte de dialog

Si l'utilisateur clique sur Refuser et clique également sur une case indiquant "ne plus jamais demander" , la méthode explain() sera utilisée pour afficher la boîte de dialog.

méthodes pour afficher les boîtes de dialog:

  private void showDialogOK(Ssortingng message, DialogInterface.OnClickListener okListener) { new AlertDialog.Builder(this) .setMessage(message) .setPositiveButton("OK", okListener) .setNegativeButton("Cancel", okListener) .create() .show(); } private void explain(Ssortingng msg){ final android.support.v7.app.AlertDialog.Builder dialog = new android.support.v7.app.AlertDialog.Builder(this); dialog.setMessage(msg) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface paramDialogInterface, int paramInt) { // permissionsclass.requestPermission(type,code); startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:com.exampledemo.parsaniahardik.marshmallowpermission"))); } }) .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface paramDialogInterface, int paramInt) { finish(); } }); dialog.show(); } 

L'extrait de code ci-dessus demande quatre permissions à la fois. Vous pouvez également demander un nombre illimité d'permissions dans votre activité, selon vos besoins.

Après beaucoup de recherches Ce code fonctionne pour moi:

Vérifiez que l’autorisation a déjà: Vérifiez l’autorisation WRITE_EXTERNAL_STORAGE Autorisé ou non?

 if(isReadStorageAllowed()){ //If permission is already having then showing the toast //Toast.makeText(SplashActivity.this,"You already have the permission",Toast.LENGTH_LONG).show(); //Existing the method with return return; }else{ requestStoragePermission(); } private boolean isReadStorageAllowed() { //Getting the permission status int result = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE); //If permission is granted returning true if (result == PackageManager.PERMISSION_GRANTED) return true; //If permission is not granted returning false return false; } //Requesting permission private void requestStoragePermission(){ if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)){ //If the user has denied the permission previously your code will come to this block //Here you can explain why you need this permission //Explain here why you need this permission } //And finally ask for the permission ActivityCompat.requestPermissions(this,new Ssortingng[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},REQUEST_WRITE_STORAGE); } 

Implémenter la méthode onRequestPermissionsResult Override pour vérifier si l’utilisateur autorise ou refuse

  @Override public void onRequestPermissionsResult(int requestCode, @NonNull Ssortingng[] permissions, @NonNull int[] grantResults) { //Checking the request code of our request if(requestCode == REQUEST_WRITE_STORAGE){ //If permission is granted if(grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){ //Displaying a toast Toast.makeText(this,"Permission granted now you can read the storage",Toast.LENGTH_LONG).show(); }else{ //Displaying another toast if permission is not granted Toast.makeText(this,"Oops you just denied the permission",Toast.LENGTH_LONG).show(); } } 

ça a fonctionné pour moi

  boolean hasPermission = (ContextCompat.checkSelfPermission(AddContactActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED); if (!hasPermission) { ActivityCompat.requestPermissions(AddContactActivity.this, new Ssortingng[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_STORAGE); } @Override public void onRequestPermissionsResult(int requestCode, Ssortingng[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case REQUEST_WRITE_STORAGE: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { //reload my activity with permission granted or use the features what required the permission } else { Toast.makeText(AddContactActivity.this, "The app was not allowed to write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show(); } } } } 
  Try this int permission = ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE); if (permission != PackageManager.PERMISSION_GRANTED) { Log.i("grant", "Permission to record denied"); if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(getSsortingng(R.ssortingng.permsg)) .setTitle(getSsortingng(R.ssortingng.permtitle)); builder.setPositiveButton(getSsortingng(R.ssortingng.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { Log.i("grant", "Clicked"); makeRequest(); } }); AlertDialog dialog = builder.create(); dialog.show(); } else { //makeRequest1(); makeRequest(); } } protected void makeRequest() { ActivityCompat.requestPermissions(this, new Ssortingng[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 500); } @Override public void onRequestPermissionsResult(int requestCode, Ssortingng permissions[], int[] grantResults) { switch (requestCode) { case 500: { if (grantResults.length == 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED) { Log.i("1", "Permission has been denied by user"); } else { Log.i("1", "Permission has been granted by user"); } return; } } } 

Avant de commencer votre téléchargement, vérifiez vos permissions d’exécution et si vous n’avez pas la permission, demandez des permissions comme cette méthode

requestStoragePermission ()

 private void requestStoragePermission(){ if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.READ_EXTERNAL_STORAGE)) { } ActivityCompat.requestPermissions(this, new Ssortingng[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull Ssortingng[] permissions, @NonNull int[] grantResults) { if(requestCode == STORAGE_PERMISSION_CODE){ if(grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){ } else{ Toast.makeText(this, "Oops you just denied the permission", Toast.LENGTH_LONG).show(); } } }