La méthode CheckSelfPermission
ne fonctionne pas comme prévu et renvoie toujours zéro dans Android 6.0 (Marshmallow). Parce que le sdk cible est 22 et que j'utilise http Client pour la connexion réseau. Voici l'extrait de code.
private void insertDummyContactWrapper() {
List<String> permissionsNeeded = new ArrayList<String>();
final List<String> permissionsList = new ArrayList<String>();
if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
permissionsNeeded.add("GPS");
if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS))
permissionsNeeded.add("Read Contacts");
if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS))
permissionsNeeded.add("Write Contacts");
if (permissionsList.size() > 0) {
if (permissionsNeeded.size() > 0) {
// Need Rationale
String message = "You need to grant access to " + permissionsNeeded.get(0);
for (int i = 1; i < permissionsNeeded.size(); i++)
message = message + ", " + permissionsNeeded.get(i);
showMessageOKCancel(message,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
}
});
return;
}
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
return;
}
insertDummyContact();
}
@TargetApi(Build.VERSION_CODES.M)
private boolean addPermission(List<String> permissionsList, String permission) {
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(permission);
// Check for Rationale Option
if (!shouldShowRequestPermissionRationale(permission)) return false;
}
return true;
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null)
.create()
.show();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: {
Map<String, Integer> perms = new HashMap<String, Integer>();
// Initial
perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.WRITE_CONTACTS, PackageManager.PERMISSION_GRANTED);
// Fill with results
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
// Check for ACCESS_FINE_LOCATION
if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
// All Permissions Granted
insertDummyContact();
} else {
// Permission Denied
Toast.makeText(MainActivity.this, "Some Permission is Denied", Toast.LENGTH_SHORT)
.show();
}
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}"
La méthode Context#checkSelfPermission(String)
a été ajoutée à l'API 23. Également en dessous de l'API 23, cela n'a pas de sens puisque l'autorisation est toujours accordée. Vérifiez la version de l'API avant de gérer les autorisations.
private void insertDummyContactWrapper() {
// the only way we insert the dummy contact if if we are below M.
// Else we continue on and Prompt the user for permissions
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
insertDummyContact();
return;
}
List<String> permissionsNeeded = new ArrayList<String>();
final List<String> permissionsList = new ArrayList<String>();
if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
permissionsNeeded.add("GPS");
if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS))
permissionsNeeded.add("Read Contacts");
if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS))
permissionsNeeded.add("Write Contacts");
if (permissionsList.size() > 0) {
if (permissionsNeeded.size() > 0) {
// Need Rationale
String message = "You need to grant access to " + permissionsNeeded.get(0);
for (int i = 1; i < permissionsNeeded.size(); i++)
message = message + ", " + permissionsNeeded.get(i);
showMessageOKCancel(message,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
}
});
return;
}
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
}
}
Si votre application cible un niveau d'API antérieur à 23 (Android M) , alors les deux: ContextCompat # checkSelfPermission et Le contexte # checkSelfPermission ne fonctionne pas et renvoie toujours 0 ( PERMISSION_GRANTED ). Même si vous exécutez l'application sur Android 6.0 (API 23).
Ce n'est pas tout à fait vrai que si vous ciblez un niveau d'API avant 23, vous n'avez pas à vous occuper des autorisations. Si vous ciblez un niveau d'API avant 23, alors:
Comme je l'ai dit au premier point, si vous ciblez un niveau d'API avant 23 sur Android 6.0, alors ContextCompat # checkSelfPermission et Context # checkSelfPermission ne fonctionne pas. Heureusement, vous pouvez utiliser PermissionChecker # checkSelfPermission pour vérifier les autorisations d'exécution.
Exemple de code:
public boolean selfPermissionGranted(String permission) {
// For Android < Android M, self permissions are always granted.
boolean result = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (targetSdkVersion >= Build.VERSION_CODES.M) {
// targetSdkVersion >= Android M, we can
// use Context#checkSelfPermission
result = context.checkSelfPermission(permission)
== PackageManager.PERMISSION_GRANTED;
} else {
// targetSdkVersion < Android M, we have to use PermissionChecker
result = PermissionChecker.checkSelfPermission(context, permission)
== PermissionChecker.PERMISSION_GRANTED;
}
}
return result;
}
Pour obtenir la version Sdk cible, vous pouvez utiliser:
try {
final PackageInfo info = context.getPackageManager().getPackageInfo(
context.getPackageName(), 0);
targetSdkVersion = info.applicationInfo.targetSdkVersion;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
Cela fonctionne sur Nexus 5 avec Android M.
Lorsque vous ciblez un niveau d'API avant 23, un mode de compatibilité s'applique. L'ancien comportement d'autorisation est en cours d'exécution, même sur les appareils exécutant Android). Pour utiliser le nouveau système d'autorisation, vous devez cibler l'API 23 (ou une version ultérieure).
Le comportement complet est spécifié dans la documentation: https://developer.Android.com/training/permissions/requesting.html