tiempo studio solicitar permission permisos permiso onrequestpermissionsresult example ejecución durante cómo code checkpermission camara android android-permissions

android - studio - request permissions request code



El método checkSelfPermission no funciona en targetSdkVersion 22 (3)

CheckSelfPermission método CheckSelfPermission no funciona como se esperaba y siempre devuelve cero en Android 6.0 (Marshmallow). Porque el SDK de destino es 22 y estoy usando el Cliente HTTP para la conexión de red. El siguiente es el fragmento de código.

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


  1. Si su aplicación está dirigida a un nivel de API antes del 23 (Android M), entonces: ContextCompat#checkSelfPermission y http://developer.android.com/reference/android/content/Context.html#checkSelfPermission(java.lang.String) no funcionan y siempre devuelve 0 ( PERMISSION_GRANTED ). Incluso si ejecuta la aplicación en Android 6.0 (API 23).

  2. No es del todo cierto que si se dirige a un nivel de API antes del 23, no tiene que ocuparse de los permisos. Si se dirige a un nivel de API antes del 23, entonces:

    • Android <6.0: Todo estará bien.
    • Android 6.0: los permisos de tiempo de ejecución de la aplicación se otorgarán de forma predeterminada (se aplica el modo de compatibilidad), pero el usuario puede cambiar los permisos de tiempo de ejecución en la configuración de Android, entonces puede tener un problema.
  3. Como dije en el primer punto, si apunta a un nivel de API anterior a 23 en Android 6.0, entonces ContextCompat#checkSelfPermission y http://developer.android.com/reference/android/content/Context.html#checkSelfPermission(java.lang.String) no funcionan. Afortunadamente, puede usar PermissionChecker#checkSelfPermission para verificar los permisos de tiempo de ejecución.

Código de ejemplo:

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

Para obtener la versión de Sdk de destino, puede usar:

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

Funciona en Nexus 5 con Android M.


Cuando se apunta a un nivel de API antes del 23, se aplica un modo de compatibilidad. El antiguo comportamiento de permisos se está ejecutando, incluso en dispositivos con Android 6. Para usar el nuevo sistema de permisos, debe apuntar a la API 23 (o superior en el futuro).

El comportamiento completo se especifica en la documentación: https://developer.android.com/training/permissions/requesting.html


El método Context#checkSelfPermission(String) se agregó a la API 23. También debajo de la API 23 no tiene sentido ya que siempre se otorga el permiso. Verifique la versión de la API antes de manejar los permisos

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

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