Gestión de Permisos en Android: Código y Buenas Prácticas

Clase 19 de 33Curso de Android: Integración de APIs nativas

Resumen

Al desarrollar aplicaciones Android que utilizan datos sensibles, como la localización del usuario o el acceso a hardware importante como la cámara, es indispensable gestionar correctamente los permisos requeridos. Android solicita dos pasos primordiales: registrar previamente los permisos en el archivo manifes y habilitarlos o solicitarlos al usuario durante la ejecución.

¿Qué tipos de permisos existen y cómo se agregan al manifiesto?

Los permisos esenciales a incluir en el manifiesto abarcan diversas funciones básicas dentro de una aplicación Android. Algunos de los permisos más comunes y relevantes son:

  • ACCESS_COARSE_LOCATION: proporciona ubicación mediante redes celulares.
  • ACCESS_FINE_LOCATION: ofrece ubicación precisa mediante GPS.

Ambos permisos deben incluirse de forma explícita en el Android manifiesto; sin embargo, el permiso ACCESS_FINE_LOCATION requiere adicionalmente autorización directa del usuario en tiempo real.

¿Cómo implementar funciones útiles para verificar permisos en código?

Para optimizar la validación de permisos en toda la aplicación, es conveniente desarrollar funciones reutilizables en forma de extensiones. La creación de un package llamado utils y dentro de él un archivo permissions utils optimiza esta práctica de programación mediante funciones que revisan si ciertos permisos están aprobados:

Verificar un permiso específico

Primero se utiliza una función básica para cualquier permiso:

private fun Context.hasPermission(permission: String): Boolean {
    return ContextCompat.checkSelfPermission(
        this,
        permission
    ) == PackageManager.PERMISSION_GRANTED
}

Luego se reutiliza para permisos concretos, como la ubicación fina:

fun Context.hasLocationPermission(): Boolean =
    hasPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)

Manejo retrocompatible de permisos

Para permisos específicos de versiones recientes, como notificaciones en Android Tiramisu, se implementa manejo condicional según el SDK:

fun Context.hasNotificationPermission(): Boolean {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        hasPermission(android.Manifest.permission.POST_NOTIFICATIONS)
    } else true
}

Y también se prevé la necesidad para acceso a cámara:

fun Context.hasCameraPermission(): Boolean =
    hasPermission(android.Manifest.permission.CAMERA)

¿Qué hacer cuando un usuario rechaza ciertos permisos?

Cuando el usuario rechaza algún permiso, Android ofrece una opción denominada Rationale, una herramienta valiosa para mejorar la experiencia de usuario. Esta función muestra un diálogo que explica detalladamente la importancia y uso especifico del permiso solicitado.

Implementando 'Rationale' para permisos

La función para mostrar una explicación sobre la necesidad del permiso toma la siguiente estructura:

fun ComponentActivity.shouldShowLocationRationalePermission(): Boolean {
    return shouldShowRequestPermissionRationale(
        android.Manifest.permission.ACCESS_FINE_LOCATION
    )
}

fun ComponentActivity.shouldShowPostNotificationRationale(): Boolean =
    Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
            shouldShowRequestPermissionRationale(android.Manifest.permission.POST_NOTIFICATIONS)

fun ComponentActivity.shouldShowCameraPermissionRationale(): Boolean =
    shouldShowRequestPermissionRationale(android.Manifest.permission.CAMERA)

Estas funciones permiten verificar si es necesario mostrar el diálogo explicativo, siguiendo buenas prácticas que recomiendan pedir permisos justo al momento requerido por la funcionalidad de la aplicación.