checkSelfPermission方法在targetSdkVersion 22中不起作用

时间:2015-10-29 06:22:57

标签: android android-permissions

" CheckSelfPermission"方法没有按预期工作,它总是在android 6.0(Marshmallow)中返回零。因为目标sdk是22,我正在使用http Client进行网络连接。以下是代码段。

" private void insertDummyContactWrapper(){         列出permissionsNeeded = new ArrayList();

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

3 个答案:

答案 0 :(得分:88)

  1. 如果您的应用程序定位到23之前的 API级别(Android M),则两者都是: ContextCompat#checkSelfPermissionContext#checkSelfPermission无法正常工作且始终返回0(PERMISSION_GRANTED)。即使您在Android 6.0(API 23)上运行该应用程序。

  2. 如果您在23之前定位API级别,则不必完全正确,那么您就不必处理权限。如果您在23之前定位API级别,那么:

    • Android&lt; 6.0:一切都会好的。
    • Android 6.0 :默认情况下会授予应用程序的运行时权限(适用兼容模式),用户可以更改运行时权限Android设置,那么您可能会遇到问题。
  3. 正如我在第1点所说,如果您在Android 6.0上定位23之前的API级别,则ContextCompat#checkSelfPermissionContext#checkSelfPermission无法正常工作。 幸运的是,您可以使用PermissionChecker#checkSelfPermission来检查运行时权限。

  4. 示例代码:

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

    要获得目标Sdk版本,您可以使用:

        try {
            final PackageInfo info = context.getPackageManager().getPackageInfo(
                    context.getPackageName(), 0);
            targetSdkVersion = info.applicationInfo.targetSdkVersion;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
    

    适用于Android M的Nexus 5

答案 1 :(得分:14)

方法Context#checkSelfPermission(String)已添加到API 23.同样在API 23之下,由于始终授予权限,因此它毫无意义。在处理权限之前检查API版本

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

参考:http://developer.android.com/reference/android/content/Context.html#checkSelfPermission(java.lang.String)

答案 2 :(得分:5)

在23之前定位API级别时,将应用兼容模式。旧的权限行为正在运行,即使在运行Android 6的设备上也是如此。要使用新的权限系统,您必须将API 23(或将来的更高版本)作为目标。

完整行为在文档中指定:https://developer.android.com/training/permissions/requesting.html