Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Descripción general de los permisos

El objetivo de un permiso es proteger la privacidad del usuario de Android. Las apps para Android deben solicitar permiso para acceder a datos sensibles del usuario (como contactos y SMS) y algunas funciones del sistema (como Internet y la cámara). Según la función, el sistema podría otorgar automáticamente el permiso o pedirle al usuario que apruebe la solicitud.

Un punto central del diseño de la arquitectura de seguridad de Android consiste en que ninguna app, de forma predeterminada, tiene permiso para realizar operaciones que pudieran tener consecuencias negativas para otras apps, el sistema operativo o el usuario. Esto incluye leer datos privados de los usuarios o escribir en ellos (por ejemplo, los contactos o los mensajes de correo electrónico), leer archivos de otra app o escribir en ellos, acceder a una red, mantener el dispositivo activo, etcétera.

En esta página se ofrece una descripción general de cómo funcionan los permisos de Android y se incluye la siguiente información: cómo se presentan los permisos al usuario, la diferencia entre solicitudes de permisos de tiempo de instalación y tiempo de ejecución, cómo se aplican los permisos, y los tipos de permisos y sus grupos. En cambio, si buscas una guía práctica para usar los permisos de las apps, consulta Cómo solicitar permisos de la app.

Aprobación de un permiso

Una app debe publicitar los permisos que requiere incluyendo etiquetas <uses-permission> en el manifiesto de la app. Por ejemplo, en el manifiesto de una app que necesite enviar mensajes SMS, debería incluirse esta línea:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.snazzyapp">

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

    <application ...>
        ...
    </application>
</manifest>

Si en el manifiesto de tu app se incluyen permisos normales (es decir, los que no presentan un gran riesgo para la privacidad del usuario o el funcionamiento del dispositivo), el sistema otorgará automáticamente esos permisos.

Si en el manifiesto de tu app se incluyen permisos riesgosos (es decir, los que podrían afectar la privacidad del usuario o el funcionamiento normal del dispositivo), como el permiso de SEND_SMS del ejemplo anterior, el sistema solicitará al usuario que otorgue explícitamente esos permisos.

Para obtener más información sobre los permisos normales y riesgosos, consulta Niveles de protección.

Solicitudes para permisos riesgosos

Solo los permisos riesgosos requieren la aprobación del usuario. El modo en el que Android le pide al usuario que otorgue permisos riesgosos depende de la versión del sistema que se ejecuta en el dispositivo del usuario y de la versión del sistema a la que se orienta tu app.

Solicitudes de tiempo de ejecución (Android 6.0 y posteriores)

Si el dispositivo tiene instalado Android 6.0 (nivel de API 23) o una versión posterior, y la targetSdkVersion de la app es de nivel 23 o posterior, el usuario no recibirá ninguna notificación de permisos durante la instalación. Tu app debe pedirle al usuario que otorgue permisos riesgosos durante el tiempo de ejecución. Cuando la app solicita un permiso, el usuario ve un diálogo del sistema (como el que se muestra en la figura 1, a la izquierda) que le indica a qué grupo de permisos está intentando acceder la app. El diálogo incluye los botones Denegar y Permitir.

Si el usuario rechaza la solicitud de permiso, la próxima vez que la app solicite el permiso, el diálogo incluirá una casilla de verificación que, si se marca, indicará que el usuario no desea que se le vuelva a pedir el permiso (consulta la figura 1, a la derecha).

Figura 1: Diálogo de permiso inicial (izquierda) y solicitud de permiso secundaria con opción de desactivar las solicitudes posteriores (derecha)

Si el usuario marca la casilla No volver a preguntar y presiona Denegar, el sistema ya no le hará pedidos si vuelves a intentar solicitar el mismo permiso.

Incluso si el usuario le otorga a la app el permiso que solicitó, esto no te garantizará que siempre lo tendrás. Además, los usuarios tienen la opción de habilitar o inhabilitar permisos uno por uno en la configuración del sistema. Siempre deberías verificar y solicitar permisos durante el tiempo de ejecución, a fin de evitar errores durante ese momento (SecurityException).

Para obtener detalles sobre cómo controlar las solicitudes de permisos de tiempo de ejecución, consulta Cómo solicitar permisos de la app.

Solicitudes en el momento de la instalación (Android 5.1.1 y anteriores)

Si el dispositivo tiene instalado Android 5.1.1 (nivel de API 22) o versiones anteriores, o si el atributo targetSdkVersion es 22 o inferior y se ejecuta en cualquier versión de Android, el sistema le pedirá automáticamente al usuario que otorgue todos los permisos riesgosos para tu app en el momento de la instalación (consulta la figura 2).

Figura 2: Diálogo de permiso en el momento de la instalación

Si el usuario hace clic en Aceptar, se otorgarán todos los permisos solicitados por la app. Si el usuario rechaza la solicitud de permisos, el sistema cancelará la instalación de la app.

Si se requieren permisos adicionales para instalar una actualización de la app, se le pedirá al usuario que acepte los nuevos permisos antes de actualizar la app.

Si necesitas una descripción general de los patrones recomendados para la experiencia del usuario en relación con las solicitudes de permisos, consulta Prácticas recomendadas sobre permisos de apps.

Para obtener información sobre cómo verificar y solicitar permisos del usuario, consulta Cómo solicitar permisos de la app.

Solicitudes para acceder a información sensible del usuario

Algunas apps dependen del acceso a la información sensible del usuario que se relaciona con sus registros de llamadas y mensajes SMS. Si quieres solicitar los permisos específicos para registros de llamadas y mensajes SMS, y publicar tu app en Play Store, debes solicitar al usuario que configure tu app como controlador predeterminado para una función principal del sistema antes de solicitar estos permisos de tiempo de ejecución.

Para obtener más información sobre los controladores predeterminados, así como orientación sobre cómo mostrar una solicitud de estos a los usuarios, consulta la guía sobre permisos que se usan solo en controladores predeterminados.

Permisos para funciones de hardware opcionales

Para acceder a algunas funciones de hardware (como Bluetooth o la cámara), se necesita un permiso de la app. Sin embargo, no todos los dispositivos Android cuentan con estas funciones de hardware. Por lo tanto, si tu app solicita el permiso de CAMERA, es importante que también incluyas la etiqueta <uses-feature> en tu manifiesto a fin de declarar si se requiere o no esta función. Por ejemplo:

<uses-feature android:name="android.hardware.camera" android:required="false" />

Si declaras android:required="false" para la función, Google Play permitirá que tu app se instale en dispositivos que no cuentan con esa función. Luego, para verificar si el dispositivo actual tiene la función durante el tiempo de ejecución, llama a PackageManager.hasSystemFeature() e inhabilita esa función correctamente, si no está disponible.

Si no proporcionas la etiqueta <uses-feature>, cuando Google Play detecte que tu app solicita el permiso correspondiente, asumirá que requiere esta función. De este modo, filtra tu app en los dispositivos que no cuentan con la función, como si declararas android:required="true" en la etiqueta <uses-feature>.

Para obtener más información, consulta Google Play y filtrado por funciones.

Permisos únicos

A partir de Android 11 (nivel de API 30), cada vez que la app solicita un permiso relacionado con la ubicación, el micrófono o la cámara, el diálogo de permisos para el usuario contiene una opción llamada Solo esta vez. Si el usuario selecciona esta opción, se le otorgará un permiso único temporal a la app.

Luego la app podrá acceder a los datos relacionados durante un período que dependerá del comportamiento de tu app y de las acciones del usuario:

  • Mientras su actividad sea visible, la app podrá acceder a los datos.
  • Si el usuario envía la app a segundo plano, esta podrá seguir accediendo a los datos durante un breve período.
  • Si inicias un servicio en primer plano mientras la actividad está visible y el usuario lleva la app a segundo plano, esta puede continuar accediendo a los datos hasta que se detenga ese servicio.
  • Si el usuario revoca el permiso único (por ejemplo, en la configuración del sistema), la app no podrá acceder a los datos, independientemente de si iniciaste un servicio en primer plano. Al igual que con cualquier otro permiso, si el usuario revoca el permiso único de la app, finalizará el proceso.

La próxima vez que el usuario abra tu app y una función requiera acceso a la ubicación, el micrófono o la cámara, se le solicitará nuevamente el permiso.

Aplicación de permisos

Los permisos no solo se utilizan para solicitar funcionalidades del sistema. Los servicios proporcionados por las apps pueden aplicar permisos personalizados para limitar su uso a determinados usuarios. Para obtener más información sobre cómo declarar permisos personalizados, consulta Define un permiso de app personalizado.

Aplicación de permisos de actividad

Los permisos aplicados con el atributo android:permission en la etiqueta <activity>, en el manifiesto, fijan restricciones respecto a los usuarios que pueden iniciar esa Activity. Se verifica el permiso durante Context.startActivity() y Activity.startActivityForResult(). Si el emisor no tiene el permiso necesario, la llamada arroja una SecurityException.

Aplicación de permiso de servicio

Los permisos aplicados con el atributo android:permission en la etiqueta <service> del manifiesto fijan restricciones respecto a los usuarios que pueden iniciarlo o vincularlo con el Service asociado. Se verifica el permiso durante Context.startService(), Context.stopService() y Context.bindService(). Si el emisor no tiene el permiso necesario, la llamada arroja una SecurityException.

Aplicación de permiso de emisión

Los permisos aplicados con el atributo android:permission en la etiqueta <receiver> fijan restricciones respecto de la autorización para enviar transmisiones al BroadcastReceiver asociado. Se controla el permiso después de que se muestra Context.sendBroadcast(), mientras el sistema intenta proporcionar la emisión enviada al receptor en cuestión. En consecuencia, un error de permisos no generará una excepción para el emisor, sino que únicamente no proporcionará el Intent.

De la misma manera, se puede suministrar un permiso a Context.registerReceiver() para tener control sobre quiénes pueden realizar transmisiones a un receptor registrado programáticamente. Por otro lado, se puede suministrar un permiso cuando se llama a Context.sendBroadcast() a fin de restringir los objetos receptores de emisión que tienen autorización para recibirla.

Ten en cuenta que tanto un receptor como un transmisor pueden requerir un permiso. Cuando esto sucede, deben aprobarse ambos controles de permisos para que se proporcione el intent al objetivo asociado. Para obtener más información, consulta Cómo usar permisos para restringir emisiones.

Aplicación de permisos de proveedor de contenido

Los permisos aplicados con el atributo android:permission en la etiqueta <provider> fijan restricciones respecto a quiénes pueden acceder a los datos en un ContentProvider. (Los proveedores de contenido disponen de un recurso adicional importante que se denomina permisos del URI y se describe a continuación). A diferencia de los otros componentes, puedes establecer dos atributos de permisos separados: android:readPermission restringe quién puede leer del proveedor y android:writePermission restringe quién puede escribir en él. Ten en cuenta que si un proveedor está protegido con un permiso de escritura y un permiso de lectura, tener el permiso de escritura no implica que puedas realizar operaciones de lectura en un proveedor.

Se controlan los permisos cuando obtienes un proveedor por primera vez (si no tienes ninguno de los permisos, se generará una SecurityException) y cuando realizas operaciones en el proveedor. Para usar ContentResolver.query(), se debe tener el permiso de lectura; para usar ContentResolver.insert(), ContentResolver.update() y ContentResolver.delete(), se debe tener el permiso de escritura. En todos estos casos, si no tienes el permiso obligatorio, la llamada genera una SecurityException.

Permisos de URI

El sistema de permisos estándar descrito hasta ahora suele no ser suficiente cuando se usa con proveedores de contenido. Es posible que un proveedor de contenido quiera protegerse con permisos de lectura y escritura, mientras que sus clientes directos también deben proporcionar URI específicos a otras apps para que puedan operar en ellas.

Un ejemplo típico es el de los archivos adjuntos en la app de correo electrónico. El acceso al correo debe estar protegido por permisos, ya que son datos sensibles del usuario. Sin embargo, si se proporciona un URI de una imagen adjunta a un visor de imágenes, este no tendrá permiso para abrir el archivo adjunto, debido a que no existirá un motivo para ello que le permita acceder a todo el correo electrónico.

La solución para este problema son los permisos por URI: cuando inicia una actividad o muestra un resultado en una actividad, el emisor puede establecer Intent.FLAG_GRANT_READ_URI_PERMISSION o Intent.FLAG_GRANT_WRITE_URI_PERMISSION. Esto otorga a la actividad receptora permisos de acceso al URI de datos específico en el intent, independientemente de que tenga permiso para acceder a los datos en el proveedor de contenido correspondiente al intent.

Este mecanismo permite emplear un modelo de estilo de capacidad común, en el cual la interacción del usuario (abrir un archivo adjunto, seleccionar un contacto de una lista, etc.) impulsa que se otorguen permisos específicos. Este puede ser un recurso clave para reducir los permisos que necesitan las apps únicamente a aquellos relacionados de manera directa con su comportamiento.

Para crear la implementación más segura que permita a otras apps tomar la responsabilidad de sus acciones dentro de tu app, debes usar permisos específicos de esta manera y declarar la compatibilidad de la app con el atributo android:grantUriPermissions o la etiqueta <grant-uri-permissions>.

Se ofrece más información en los métodos Context.grantUriPermission(), Context.revokeUriPermission() y Context.checkUriPermission().

Aplicación de otros permisos

Se pueden aplicar los permisos específicos arbitrarios a un servicio, en cualquier llamada, lo que se logra con el método Context.checkCallingPermission(). Realiza una llamada con la string de permiso, que mostrará un número entero que indicará si se otorgó ese permiso al proceso de llamada actual. Ten en cuenta que esto solo se puede usar cuando ejecutas una llamada que ingresa de otro proceso; por lo general, mediante una interfaz IDL publicada por un servicio o proporcionada de alguna manera diferente a otro proceso.

Existen varias otras formas útiles de controlar los permisos. Si tienes el ID de otro proceso (PID), puedes usar el método contextual Context.checkPermission() para verificar un permiso según ese PID. Si tienes el nombre del paquete de otra app, puedes usar el método PackageManager.checkPermission() para averiguar si se le otorgó un permiso específico a ese paquete en particular.

Permisos de restablecimiento automático de apps que no se usan

Si tu app está orientada a Android 11 (nivel de API 30) o a versiones posteriores y no se usó durante algunos meses, el sistema restablecerá automáticamente los permisos de tiempo de ejecución sensibles que el usuario otorgó a la app a fin de proteger sus datos. Esta acción tiene el mismo efecto que si el usuario viera un permiso en la configuración del sistema y cambiara el nivel de acceso de tu app a Rechazar.

Si tu app sigue las prácticas recomendadas para solicitar permisos durante el tiempo de ejecución, no es necesario que realices ningún cambio.

Cómo solicitar al usuario que inhabilite el restablecimiento automático

Si es necesario, puedes pedirle al usuario que evite que el sistema restablezca los permisos de tu app. Esto es útil en situaciones en las que los usuarios esperan que tu app funcione principalmente en segundo plano, incluso sin interactuar con ella, como en los siguientes casos prácticos:

Figura 3: El usuario inhabilitó el restablecimiento automático de permisos para una aplicación determinada.
  • Para brindar contenido apto para todo público
  • Para sincronizar datos
  • Para comunicarse con dispositivos inteligentes
  • Para vincularse con dispositivos complementarios

Para direccionar al usuario a la página de tu app en la configuración del sistema, invoca un intent que incluya la acción de intent Intent.ACTION_AUTO_REVOKE_PERMISSIONS. Desde esta pantalla, los usuarios pueden evitar que el sistema restablezca los permisos de tu app de la siguiente manera:

  1. Presiona la opción Permissions, que carga la pantalla de configuración App permissions.
  2. Desactiva la opción Remove permissions if app isn't used, como se muestra en la figura 3.

Cómo determinar si el restablecimiento automático está inhabilitado

Para comprobar si la función de restablecimiento automático está inhabilitada, llama a isAutoRevokeWhitelisted(). Si este método muestra true, el sistema no restablece automáticamente los permisos de tu app.

Cómo probar la función de restablecimiento automático

A fin de verificar si el sistema restablece los permisos de tu app, haz lo siguiente:

  1. Registra el tiempo predeterminado que el sistema espera para restablecer los permisos de una app. De esa manera, puedes restablecerla después de realizar las pruebas:

    threshold=$(adb shell device_config get permissions \
      auto_revoke_unused_threshold_millis2)
    
  2. Reduce el tiempo que el sistema espera para restablecer los permisos. En el siguiente ejemplo, se modifica el sistema de manera que restablezca los permisos de una app solo un segundo después de que dejas de interactuar con ella:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 1000
    
  3. Invoca el proceso de restablecimiento automático de forma manual, como se muestra en el siguiente fragmento. Antes de ejecutar este comando, asegúrate de que se haya activado durante unos segundos el dispositivo de prueba.

    adb shell cmd jobscheduler run -u 0 -f \
      com.google.android.permissioncontroller 2
    
  4. Verifica que tu app pueda controlar el evento de restablecimiento automático.

  5. Restablece el tiempo predeterminado que el sistema espera antes de restablecer automáticamente los permisos de una app:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 $threshold
    

Otorgamientos automáticos de permisos nuevos

Con el tiempo, es posible que se agreguen restricciones nuevas a la plataforma a fin de que, para usar determinadas API, tu app deba solicitar un permiso que antes no necesitaba. Debido a que las apps existentes suponen que el acceso a esas API es libre, Android puede implementar la solicitud del permiso nuevo en el manifiesto de la app para evitar dañarla en la versión nueva de la plataforma (por lo tanto, permite que tu app herede el permiso). Android toma las decisiones relacionadas con el hecho de que una app podría necesitar el permiso según el valor indicado para el atributo targetSdkVersion. Si el valor es inferior al de la versión en la cual el permiso se agregó, Android agregará el permiso.

Por ejemplo, se aplica el permiso READ_EXTERNAL_STORAGE a partir del nivel de API 19 para restringir el acceso a los espacios de almacenamiento compartido. Si tu atributo targetSdkVersion es 18 o inferior, se agrega este permiso a la app en versiones nuevas de Android.

Precaución: Si se agrega automáticamente un permiso a tu app, en Google Play la app indicará que necesita estos permisos adicionales, aunque podría no necesitarlos realmente. A fin de evitar esto y quitar los permisos predeterminados que no necesitas, siempre actualiza el atributo targetSdkVersion para que tenga el valor más alto posible. En la documentación de Build.VERSION_CODES, puedes ver los permisos agregados en cada versión.

Niveles de protección

Los permisos se dividen en varios niveles de protección. El nivel de protección determina si se necesitan solicitudes de permiso de tiempo de ejecución.

Hay tres niveles de protección que afectan a apps de terceros: permisos normales, de firma y riesgosos. Para ver el nivel de protección de un permiso en particular, visita la página de referencia de la API de permisos.

Permisos normales

Los permisos normales abarcan áreas en las cuales tu app tiene que acceder a datos o recursos fuera de su zona de pruebas, pero donde existe un riesgo mínimo para la privacidad del usuario o el funcionamiento de otras apps. Por ejemplo, el permiso para establecer la zona horaria es un permiso normal.

Si una app declara que necesita un permiso normal, el sistema le otorgará automáticamente el permiso. El sistema no le solicita al usuario que otorgue permisos normales y los usuarios no pueden revocar estos permisos.

Permisos de firma

El sistema otorga estos permisos en el momento de la instalación, pero solo cuando la app que intenta usar un permiso tiene la firma del mismo certificado que la app que define el permiso.

Permisos riesgosos

Los permisos riesgosos abarcan áreas en las cuales la app requiere datos o recursos que incluyen información privada del usuario, o bien que podrían afectar los datos almacenados del usuario o el funcionamiento de otras apps. Por ejemplo, la capacidad de leer los contactos del usuario es un permiso riesgoso. Si una app declara que necesita un permiso riesgoso, el usuario tiene que otorgarle explícitamente el permiso. Hasta que el usuario aprueba el permiso, la app no puede ofrecer funcionalidades que dependan de ese permiso.

Para usar un permiso riesgoso, tu app debe solicitar al usuario que otorgue el permiso durante el tiempo de ejecución. Si quieres obtener más detalles sobre cómo se le solicitan permisos al usuario, consulta Solicitud de permiso riesgoso.

Permisos especiales

Un par de permisos no se comportan como normales ni riesgosos. SYSTEM_ALERT_WINDOW y WRITE_SETTINGS son particularmente sensibles; por ello, la mayoría de las apps no deben usarlos.

En la mayoría de los casos, una app debe declarar el permiso SYSTEM_ALERT_WINDOW en el manifiesto y enviar un intent en el que se solicite la autorización del usuario. El sistema responde al intent mostrando una pantalla de administración detallada al usuario.

A partir de Android 11 (nivel de API 30), las apps que invocan la acción de intent ACTION_MANAGE_OVERLAY_PERMISSION no pueden especificar un paquete. Cuando las apps invocan un intent que incluye esta acción de intent, el usuario debe seleccionar primero la app a la que desea otorgarle o revocarle el permiso. Este comportamiento se implementó para proteger a los usuarios y hacer que el otorgamiento de permisos sea más intencional.

Para obtener información sobre cómo solicitar estos permisos, consulta las entradas de referencia SYSTEM_ALERT_WINDOW y WRITE_SETTINGS.

Puedes encontrar los permisos que proporciona el sistema Android en Manifest.permission.

Grupos de permisos

Los permisos se organizan en grupos relacionados con las capacidades o funciones de un dispositivo. En este sistema, las solicitudes de permisos se controlan a nivel grupal y un grupo de permisos individual corresponde a varias declaraciones de permisos en el manifiesto de la app. Por ejemplo, el grupo de SMS incluye las declaraciones READ_SMS y RECEIVE_SMS. Agrupar permisos de esta manera permite al usuario tomar decisiones más significativas y fundamentadas sin verse abrumado por solicitudes de permisos complejas y técnicas.

Todos los permisos riesgosos de Android pertenecen a grupos de permisos. Cualquier permiso puede pertenecer a un grupo de permisos, independientemente del nivel de protección. Sin embargo, el grupo de un permiso solo afecta la experiencia del usuario si es riesgoso.

Si el dispositivo tiene Android 6.0 (nivel de API 23) instalado y el atributo targetSdkVersion de la app es 23 o un valor superior, el siguiente comportamiento del sistema tiene lugar cuando tu app solicita un permiso riesgoso:

  • Si la app no tiene permisos actualmente en el grupo de permisos, el sistema mostrará al usuario el diálogo de solicitud de permiso en el que se describe el grupo de permisos al cual la app desea acceder. En diálogo, no se describe el permiso específico dentro de ese grupo. Por ejemplo, si una app solicita el permiso READ_CONTACTS, el diálogo del sistema solo indicará que la app necesita acceder a los contactos del dispositivo. Si el usuario brinda la aprobación, el sistema otorgará a la app solamente el permiso que solicitó.
  • Si la app ya tiene otro permiso riesgoso en el mismo grupo de permisos, el sistema otorgará de inmediato el permiso, sin interactuar con el usuario. Por ejemplo, si a una app ya se le otorgó el permiso READ_CONTACTS y, luego, esta solicita el permiso WRITE_CONTACTS, el sistema lo otorga de inmediato sin mostrar el diálogo de permisos al usuario.

Precaución: Es posible que las versiones futuras del SDK de Android trasladen un permiso en particular de un grupo a otro. Por lo tanto, no debes basar la lógica de tu app en la estructura de estos grupos de permisos.

Por ejemplo, READ_CONTACTS está en el mismo grupo de permisos que WRITE_CONTACTS desde Android 8.1 (nivel de API 27). Si tu app solicita el permiso READ_CONTACTS y, luego, solicita el permiso WRITE_CONTACTS, no debes asumir que el sistema puede otorgar automáticamente el permiso WRITE_CONTACTS.

Si el dispositivo tiene instalado Android 5.1 (nivel de API 22) o versiones anteriores, o si el atributo targetSdkVersion de la app es 22 o inferior, el sistema solicitará al usuario que otorgue el permiso en el momento de la instalación. Nuevamente, el sistema solo dice al usuario qué grupos de permisos necesita la app y no los permisos individuales. Por ejemplo, cuando una app solicita READ_CONTACTS, el diálogo de instalación enumera el grupo Contactos. Cuando el usuario acepta, solo se otorga el permiso READ_CONTACTS a la app.

Nota: De todos modos, tu app debe solicitar de manera explícita cada uno de los permisos que necesita, aunque el usuario haya otorgado otro del mismo grupo. Además, la forma de agrupar permisos puede modificarse en futuras versiones de Android. Tu código no debería tener una lógica que dependa de un conjunto de permisos en particular que estén dentro de un mismo grupo.

Cómo ver los permisos de una app

Puedes ver todos los permisos definidos actualmente en el sistema usando la app de Configuración y el comando de shell adb shell pm list permissions. Para usar la app de Configuración, ve a Configuración > Apps. Elige una app y desplázate hacia abajo para ver los permisos que usa. Para los desarrolladores, la opción "-s" de la herramienta adb muestra los permisos con un aspecto similar al que observarán los usuarios:

$ adb shell pm list permissions -s
All Permissions:

Network communication: view Wi-Fi state, create Bluetooth connections, full
internet access, view network state

Your location: access extra location provider commands, fine (GPS) location,
mock location sources for testing, coarse (network-based) location

Services that cost you money: send SMS messages, directly call phone numbers

...

Además, puedes usar la opción -g de adb para otorgar automáticamente todos los permisos cuando instales una app en un emulador o un dispositivo de prueba:

$ adb shell install -g MyApp.apk

Recursos adicionales

  • Cómo solicitar permisos de la app: es la guía práctica para solicitar permisos en tu app.
  • Permisos que implican requisitos de funciones: contiene información sobre cómo la solicitud de algunos permisos restringirá implícitamente tu app a dispositivos que incluyan la característica de hardware o software correspondiente.
  • <uses-permission>: contiene referencia de la API para la etiqueta del manifiesto que declara los permisos necesarios de tu app.
  • Compatibilidad con dispositivos: incluye información acerca de cómo funciona Android en diferentes tipos de dispositivos e introducción a la manera en que puedes optimizar tu app para cada dispositivo o restringir la disponibilidad de esta para diferentes dispositivos.
  • Información general de seguridad de Android: contiene un análisis detallado del modelo de seguridad de la plataforma Android.
  • "Mother, May I?" Asking for Permissions: en este video (en inglés) de Android Dev Summit de 2015, se describen las prácticas recomendadas para solicitar permisos.
  • Android M Permissions: en este video (en inglés) de Google I/O 2015, se explican los cambios realizados en el modelo de permisos de Android 6.0.