checkSelfPermission devolviendo PERMISSION_GRANTED para el permiso revocado con targetSdkVersion <= 22

Estoy estudiando el nuevo modelo de permiso de Android Marshmallow, pero me enfrento a un problema que me parece extraño.

Una aplicación con targetSdkVersion 22 (por lo que todavía no utiliza el nuevo modelo de permiso de Android Marshmallow) declara el permiso READ_CONTACTS en el manifiesto:

 <uses-permission android:name="android.permission.READ_CONTACTS" /> 

y trata de leer el número de teléfono de un contacto a través de Intent.ACTION_PICK :

 Intent intent = new Intent(Intent.ACTION_PICK); intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE); startActivityForResult(intent, PICK_CONTACT_REQUEST); 

Cuando se ejecuta en un dispositivo con Marshmallow MRA58K, después de revocar el permiso después de instalar la aplicación a través de ADB, el método ContextCompat.checkSelfPermission() devuelve PERMISSION_GRANTED pero la operación falla más tarde cuando se accede a los contactos porque se devuelve un cursor sin registros. Como he entendido, esta es la estrategia de "retrocompatibilidad" por defecto para evitar que la aplicación heredada se bloquee.

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == PICK_CONTACT_REQUEST && resultCode == Activity.RESULT_OK) { Log.i("", "Permission granted: " + (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED)); Uri contactUri = data.getData(); Cursor c = null; try { c = getContentResolver().query(contactUri, new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER}, null, null, null); if (c != null && c.moveToFirst()) { Log.i("", "got phone number: " + c.getString(0)); } else { Log.w("", "No data received"); } } catch (Exception e) { e.printStackTrace(); } finally { if (c != null) { c.close(); } } } else { super.onActivityResult(requestCode, resultCode, data); } } 

¿Cómo puedo detectar de forma segura al usuario antes del permiso antes de intentar la operación?

También probé el ejemplo oficial de Google en https://github.com/googlesamples/android-RuntimePermissions estableciendo el targetSdkVersion a 22 con el mismo resultado: registra que el permiso se concede incluso si el usuario lo revocó, y entonces la operación falla .

Gracias 😉

Utilice el archivo android.support.v4.content.PermissionChecker

https://developer.android.com/reference/android/support/v4/content/PermissionChecker.html

Para usar los nuevos modelos de permisos (y comprobar si su aplicación tiene o no el permiso) necesita actualizar su SDK de destino a 23. No tiene sentido mantener el objetivo 22.

  • Ni el usuario 10102 ni el proceso actual tienen android.permission.READ_PHONE_STATE
  • Androide: la cámara no se abre en el malvavisco
  • Android M - comprobar el permiso de ejecución - cómo determinar si el usuario marcó "Nunca preguntar de nuevo"?
  • Android M está escuchando android.os.action.DEVICE_IDLE_MODE_CHANGED
  • ActivityCompat.requestPermissions no funciona
  • Opción de fuente de audio en la opción de desarrollador en Android M
  • Android M onRequestPermissionsResult en no actividad
  • Android: utiliza la API de huellas dactilares en la API de Android 17
  • Wakelock y modo doze
  • Modo Doze y espera de aplicación
  • Android Marshmallow ART "No se pudo encontrar el offset nativo para dex" crash
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.