Cómo solicitar permisos especiales

Un permiso especial protege el acceso a los recursos del sistema que son particularmente sensibles o no están relacionados directamente con la privacidad del usuario. Estos permisos son diferentes a los permisos en el momento de la instalación y los permisos de tiempo de ejecución.

Figura 1: La pantalla de Acceso especial de apps en la configuración del sistema

Se requieren permisos especiales para algunas de las siguientes acciones:

  • Programar alarmas exactas
  • Mostrar otras apps y dibujar sobre ellas
  • Acceder a todos los datos de almacenamiento

Las apps que declaran un permiso especial se muestran en la página Acceso especial de apps en la configuración del sistema (Figura 1). Para otorgar un permiso especial de la app, el usuario debe navegar a esta página: Configuración > Apps > Acceso especial de apps.

Flujo de trabajo

Para solicitar un permiso especial, haz lo siguiente:

  1. En el archivo de manifiesto de la app, declara los permisos especiales que podría necesitar.
  2. Diseña la UX de tu app para que se asocien determinadas acciones con permisos especiales específicos. Permite que los usuarios sepan qué acciones pueden requerir la habilitación de un permiso para que la app acceda a sus datos privados.
  3. Espera a que el usuario invoque la tarea o acción de la app que requiere acceso a datos privados específicos. En ese momento, la app puede solicitar el permiso especial necesario para acceder a esos datos.
  4. Verifica si el usuario ya otorgó el permiso especial que requiere la app. Para hacerlo, usa la función de verificación personalizada de cada permiso. Si se otorga, tu app puede acceder a los datos privados del usuario. De lo contrario, continúa con el paso siguiente. Nota: Debes verificar si tienes el permiso cada vez que realices una operación que lo requiera.
  5. Muéstrale una justificación al usuario en un elemento de la IU en la que se explique, con claridad, a qué datos intenta acceder la app y qué beneficios puede proporcionarle si otorga el permiso especial. Además, como tu app envía a los usuarios a la configuración del sistema para otorgar el permiso, también debes incluir instrucciones breves que expliquen cómo los usuarios pueden otorgar el permiso allí. La IU de justificación debe proporcionar una opción clara para que el usuario rechace otorgar el permiso. Después de que el usuario acepte la justificación, continúa con el siguiente paso.
  6. Solicita el permiso especial que requiere tu app para poder acceder a los datos privados del usuario. Es probable que implique un intent en la página correspondiente de la configuración del sistema en la que el usuario puede otorgar el permiso. A diferencia de los permisos de tiempo de ejecución, no hay diálogos emergentes para el permiso.
  7. Verifica la respuesta del usuario, si eligió otorgar o denegar el permiso especial, en el método onResume().
  8. Si el usuario otorgó el permiso a tu app, esta podrá acceder a sus datos privados. En cambio, si el usuario rechazó el permiso, deberás reducir la experiencia en la app de forma elegante para que siga proporcionando funcionalidad, sin la información protegida por ese permiso.
Figura 2: Flujo de trabajo para declarar y solicitar permisos especiales en Android.

Cómo solicitar permisos especiales

A diferencia de los permisos de tiempo de ejecución, el usuario debe otorgar permisos especiales desde la página de Acceso especial de apps en la configuración del sistema. Las apps pueden enviar a los usuarios allí con un intent, que detiene la app e inicia la página de configuración correspondiente para un permiso especial determinado. Después de que el usuario vuelve a la app, esta puede verificar si se otorgó el permiso en la función onResume().

En el siguiente código de muestra, se muestra la manera de solicitarles el permiso especial SCHEDULE_EXACT_ALARMS a los usuarios:

val alarmManager = getSystemService<AlarmManager>()!!
when {
   // if permission is granted, proceed with scheduling exact alarms…
   alarmManager.canScheduleExactAlarms() -> {
       alarmManager.setExact(...)
   }
   else -> {
       // ask users to grant the permission in the corresponding settings page
       startActivity(Intent(ACTION_REQUEST_SCHEDULE_EXACT_ALARM))
   }
}

Código de muestra para verificar el permiso y controlar las decisiones del usuario en onResume():

override fun onResume() {
   // ...

   if (alarmManager.canScheduleExactAlarms()) {
       // proceed with the action (setting exact alarms)
       alarmManager.setExact(...)
   }
   else {
       // permission not yet approved. Display user notice and gracefully degrade
       your app experience.
       alarmManager.setWindow(...)
   }
}

Prácticas recomendadas y sugerencias

En las siguientes secciones, se proporcionan algunas prácticas recomendadas y consideraciones para solicitar permisos especiales.

Cada permiso tiene su propio método de verificación

Los permisos especiales funcionan de manera diferente a los permisos de tiempo de ejecución. En su lugar, consulta la página de referencia de la API de permisos y usa las funciones para la verificación de acceso personalizado para cada permiso especial. Los ejemplos incluyen AlarmManager#canScheduleExactAlarms() para el permiso SCHEDULE_EXACT_ALARMS y Environment#isExternalStorageManager() para el permiso MANAGE_EXTERNAL_STORAGE.

Solicitud en contexto

Al igual que los permisos de tiempo de ejecución, las apps deben solicitar permisos especiales en contexto cuando el usuario solicita una acción específica que lo requiere. Por ejemplo, espera a solicitar el permiso SCHEDULE_EXACT_ALARMS hasta que el usuario programe un correo electrónico para que se envíe a una hora específica.

Explica la solicitud

Proporciona una justificación antes de redireccionar a la configuración del sistema. Como los usuarios abandonan la app temporalmente para otorgar permisos especiales, muestra una IU integrada en la app antes de iniciar el intent en la página de Acceso especial de apps en la configuración del sistema. Esta IU debe explicar claramente por qué la app necesita el permiso y cómo el usuario debe otorgarlo en la página de configuración.