checkSelfPermission方法在targetSdkVersion 22中不起作用

“CheckSelfPermission”方法没有按预期工作,它总是在Android 6.0(棉花糖)返回零。 因为目标sdk是22,我正在使用http客户端进行networking连接。 以下是代码片段。

“private void insertDummyContactWrapper(){List permissionsNew = 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); } }" 

Solutions Collecting From Web of "checkSelfPermission方法在targetSdkVersion 22中不起作用"

方法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)

  1. 如果您的应用程序的目标是23(API M)之前API级别,则两者都是: ContextCompat#checkSelfPermission和Context#checkSelfPermission不起作用,并始终返回0( PERMISSION_GRANTED )。 即使您在Android 6.0(API 23)上运行应用程序。

  2. 如果您在23之前定位API级别,那么您不必pipe理权限。 如果您在23之前针对API级别,那么:

    • Android <6.0:一切都会好的。
    • Android 6.0:默认授予应用程序的运行时权限(适用于兼容模式), 用户可以在Android设置中更改运行时权限,则可能会遇到问题。
  3. 正如我在第一点中所说的,如果您在Android 6.0之前的23之前定位API级别,那么ContextCompat#checkSelfPermission和Context#checkSelfPermission不起作用。 幸运的是,您可以使用PermissionChecker#checkSelfPermission来检查运行时权限。

示例代码:

  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。

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

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