J'ai ajouté uses-permission
, y compris WRITE_EXTERNAL_STORAGE
, MOUNT_UNMOUNT_FILESYSTEMS
, READ_EXTERNAL_STORAGE
à AndroidManifest.xml
.
Lorsque j'ai essayé d'exécuter mon application dans Nexus5 (Android 6.0), une exception s'est produite comme suit:
Java.io.IOException: open failed: EACCES (Permission denied)
Et j'ai essayé un autre téléphone Android (Android 5.1), tout était OK. Voici le code:
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, ".jpg", storageDir);
currentPhotoPath = image.getAbsolutePath();
return image;
}
Est-ce que Android 6.0 a une différence concernant l'autorisation?
Android a ajouté un nouveau modèle de permission pour Android 6.0 (Marshmallow) .
Donc, vous devez vérifier Runtime Permission
:
Que sont les autorisations d'exécution?
Avec Android 6.0 Marshmallow, Google a introduit un nouveau modèle d'autorisation qui permet aux utilisateurs de mieux comprendre pourquoi une application peut demander des autorisations spécifiques. Plutôt que d'accepter aveuglément toutes les autorisations au moment de l'installation, l'utilisateur est maintenant invité à accepter les autorisations nécessaires, le cas échéant, lors de l'utilisation de l'application.
Quand implémenter le nouveau modèle?
il ne nécessite pas de support complet tant que vous n'avez pas choisi de cibler la version 23 dans votre application. Si vous ciblez la version 22 ou une version ultérieure, votre application demandera toutes les autorisations au moment de l’installation, comme elle le ferait pour tout périphérique fonctionnant sous un système d’exploitation sous Marshmallow.
Cette information est prise à partir d'ici:
S'il vous plaît vérifier Comment mettre en œuvre à partir de ce lien:
Dans Android 6 (Marshmallow) , même si l'utilisateur a accepté toutes vos autorisations au moment de l'installation, il peut ultérieurement décider de vous retirer certaines de ces autorisations. .
Solution rapide mais non recommandée: Peut-être que si vous changez votre targetSdkVersion
dans le dégradé en 22
, le problème sera résolu.
Comment mettre en œuvre? (Meilleures pratiques)
Commencez par déterminer si le périphérique de l'utilisateur est un périphérique Marshmallow ou non:
private boolean shouldAskPermission(){
return(Build.VERSION.SDK_INT>Build.VERSION_CODES.Lollipop_MR1);
}
Si shouldAskPermission()
renvoie true
, demandez la permission dont vous avez besoin:
String[] perms = {"Android.permission.WRITE_EXTERNAL_STORAGE"};
int permsRequestCode = 200;
requestPermissions(perms, permsRequestCode);
La méthode requestPermissions(String[] permissions, int requestCode);
est une méthode publique trouvée à l'intérieur de la classe d'activité Android.
Vous recevrez les résultats de votre demande dans la méthode onRequestPermissionResult comme indiqué ci-dessous:
@Override
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){
switch(permsRequestCode){
case 200:
boolean writeAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED;
break;
}
}
Après avoir reçu les résultats, vous devrez les traiter correctement.
Flux d'autorisations suggéré:
Plus d'infos:
Un utilisateur possédant un périphérique Marshmallow aura désormais la possibilité de révoquer des autorisations dangereuses via les paramètres de l'application.
Android définit certaines autorisations comme " dangereuses " et certaines autorisations comme " normales . ”Les deux sont obligatoires dans le manifeste de votre application, mais seules les autorisations dangereuses requièrent une demande d'exécution.
Si vous avez choisi de ne pas implémenter le nouveau modèle d'autorisations (demande d'exécution), la révocation d'autorisations peut entraîner des expériences utilisateur non souhaitées et, dans certains cas, un blocage de l'application.
Le tableau ci-dessous répertorie toutes les autorisations dangereuses actuelles et leurs groupes respectifs:
Si l'utilisateur accepte une autorisation dans un groupe/catégorie, il accepte l'intégralité du groupe!
Source: http://www.captechconsulting.com
Utilisation de la bibliothèque Dexter:
Vous pouvez utiliser Dexter . Android bibliothèque qui simplifie le processus de demande d’autorisation au moment de l’exécution.
Vous pouvez également utiliser ActivityCompat.requestPermissions pour la compatibilité en amont.
exemple:
private static final int REQUEST_CODE = 0x11;
String[] permissions = {"Android.permission.WRITE_EXTERNAL_STORAGE"};
ActivityCompat.requestPermissions(this, permissions, REQUEST_CODE); // without sdk version check
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// save file
} else {
Toast.makeText(getApplicationContext(), "PERMISSION_DENIED", Toast.LENGTH_SHORT).show();
}
}
}
À partir de l’API-23, vous devez déclarer l’autorisation en activité même si vous l’avez déjà déclaré dans le manifeste.
// Storage Permissions variables
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
//persmission method.
public static void verifyStoragePermissions(Activity activity) {
// Check if we have read or write permission
int writePermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
int readPermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE);
if (writePermission != PackageManager.PERMISSION_GRANTED || readPermission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so Prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
Pour l'utiliser, appelez simplement verifyStoragePermissions(this);
dans onCreate. Cela devrait le faire avec espoir.
Si vous êtes paresseux, rétrogradez simplement targetSdkVersion à 22 (avant Lollipop)
Cela a fonctionné pour moi.
Allez dans Paramètres -> Applications -> VotreApp -> Accordez des autorisations pour Stockage, Contacts, etc.