web-dev-qa-db-fra.com

La méthode checkSelfPermission ne fonctionne pas dans targetSdkVersion 22

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);
    }
}"
39
Mithun S

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

Référence: http://developer.Android.com/reference/Android/content/Context.html#checkSelfPermission (Java.lang.String)

16
JBirdVegas
  1. 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).

  2. 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:

    • Android <6.0: Tout ira bien.
    • Android 6.0: Les autorisations d'exécution de l'application seront accordées par défaut (le mode de compatibilité s'applique), mais L'utilisateur peut modifier les autorisations d'exécution dans Android Paramètres, il se peut alors que vous rencontriez un problème.
  3. 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.

88
MikePtr

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

5
Marc Plano-Lesay