Cuando una función de tu app necesite acceso a la ubicación, espera hasta que el usuario interactúe con ella para solicitar el permiso. Este flujo de trabajo sigue la práctica recomendada de solicitar permisos de tiempo de ejecución en contexto, como se describe en la guía donde se explica cómo solicitar permisos de la app.
En la figura 1, se muestra un ejemplo de cómo realizar este proceso. La app contiene una función de "compartir ubicación" que requiere acceso a la ubicación en primer plano. Sin embargo, la app no solicita el permiso de ubicación hasta que el usuario selecciona el botón Compartir ubicación (Share Location).
El usuario puede otorgar solo la ubicación aproximada
En Android 12 (nivel de API 31) o versiones posteriores, los usuarios pueden solicitar que tu app solo recupere información de ubicación aproximada, incluso cuando tu app solicite el permiso de tiempo de ejecución ACCESS_FINE_LOCATION
.
Para controlar este posible comportamiento del usuario, no solicites el permiso ACCESS_FINE_LOCATION
por sí solo. En su lugar, solicita los permisos ACCESS_FINE_LOCATION
y ACCESS_COARSE_LOCATION
en una sola solicitud de tiempo de ejecución. Si intentas solicitar solo ACCESS_FINE_LOCATION
, el sistema ignorará la solicitud en algunas versiones de Android 12. Si tu app está orientada a Android 12 o versiones posteriores, el sistema registra el siguiente mensaje de error en Logcat:
ACCESS_FINE_LOCATION must be requested with ACCESS_COARSE_LOCATION.
Cuando la app solicita ACCESS_FINE_LOCATION
y ACCESS_COARSE_LOCATION
, el diálogo de permisos del sistema incluye las siguientes opciones para el usuario:
- Precisa: Permite que la app obtenga información de ubicación precisa.
- Aproximada: Permite que la app obtenga solo la información de ubicación aproximada.
En la figura 3, se muestra que el diálogo incluye una indicación visual para ambas opciones que permite que el usuario elija. Después de que el usuario decide la precisión de la ubicación, presiona uno de los tres botones para seleccionar la duración del otorgamiento del permiso.
En Android 12 y versiones posteriores, los usuarios pueden navegar hasta la configuración del sistema para establecer la precisión preferida de la ubicación para cualquier app, independientemente de la versión de su SDK de destino. Esto se aplica incluso cuando tu app está instalada en un dispositivo con Android 11 o una versión anterior, y luego el usuario actualiza el dispositivo a Android 12 o una versión posterior.
La elección del usuario afecta los otorgamientos de permisos
En la siguiente tabla, se muestran los permisos que el sistema otorga a la app, según las opciones que el usuario elige en el diálogo de tiempo de ejecución de permisos:
Precisa | Aproximada | |
---|---|---|
Mientras la app está en uso | ACCESS_FINE_LOCATION y ACCESS_COARSE_LOCATION |
ACCESS_COARSE_LOCATION |
Solo esta vez | ACCESS_FINE_LOCATION y ACCESS_COARSE_LOCATION |
ACCESS_COARSE_LOCATION |
Denegar | Sin permisos de ubicación | Sin permisos de ubicación |
Para determinar qué permisos le otorgó el sistema a la app, verifica el valor que se muestra de la solicitud de permisos. Puedes usar bibliotecas de Jetpack en código similar al siguiente o puedes usar bibliotecas de plataforma, en las que administras por tu cuenta el código de solicitud de permiso.
Kotlin
@RequiresApi(Build.VERSION_CODES.N) fun requestPermissions() { val locationPermissionRequest = registerForActivityResult( ActivityResultContracts.RequestMultiplePermissions() ) { permissions -> when { permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false) -> { // Precise location access granted. } permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false) -> { // Only approximate location access granted. } else -> { // No location access granted. } } } // Before you perform the actual permission request, check whether your app // already has the permissions, and whether your app needs to show a permission // rationale dialog. For more details, see Request permissions: // https://developer.android.com/training/permissions/requesting#request-permission locationPermissionRequest.launch( arrayOf( Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION ) ) }
Java
private void requestPermissions() { ActivityResultLauncher<String[]> locationPermissionRequest = registerForActivityResult(new ActivityResultContracts .RequestMultiplePermissions(), result -> { Boolean fineLocationGranted = null; Boolean coarseLocationGranted = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { fineLocationGranted = result.getOrDefault( Manifest.permission.ACCESS_FINE_LOCATION, false); coarseLocationGranted = result.getOrDefault( Manifest.permission.ACCESS_COARSE_LOCATION,false); } if (fineLocationGranted != null && fineLocationGranted) { // Precise location access granted. } else if (coarseLocationGranted != null && coarseLocationGranted) { // Only approximate location access granted. } else { // No location access granted. } } ); // ... // Before you perform the actual permission request, check whether your app // already has the permissions, and whether your app needs to show a permission // rationale dialog. For more details, see Request permissions. locationPermissionRequest.launch(new String[] { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION }); }
Solicita que se actualice el permiso a la ubicación precisa
Puedes pedirle al usuario que actualice el acceso de tu app de la ubicación aproximada a la ubicación precisa. Antes de solicitarle al usuario que actualice el acceso de la app a ubicación precisa, considera si el caso de uso de la app necesita, en realidad, este nivel de precisión. Si la app necesita sincronizar un dispositivo con otros cercanos por Bluetooth o Wi-Fi, procura usar la sincronización de dispositivos complementarios o los permisos de Bluetooth, en lugar de solicitar el permiso ACCESS_FINE_LOCATION
.
Para solicitarle al usuario que actualice el acceso a la ubicación de la app de aproximada a precisa, haz lo siguiente:
- Si es necesario, explica el motivo por el que la app necesita el permiso.
- Vuelve a solicitar juntos los permisos
ACCESS_FINE_LOCATION
yACCESS_COARSE_LOCATION
. Como el usuario ya permitió que el sistema le otorgue la ubicación aproximada a la app, esta vez, el diálogo del sistema es diferente, como se muestra en las figuras 4 y 5:
Solicita inicialmente solo la ubicación en primer plano
Incluso si varias funciones de tu app requieren acceso a la ubicación, es probable que solo algunas de ellas necesiten acceso a la ubicación en segundo plano. Por lo tanto, se recomienda que tu app realice solicitudes incrementales de permisos para obtener primero acceso a la ubicación en primer plano, y luego acceso a la ubicación en segundo plano. Cuando se realizan solicitudes incrementales, les brindas a los usuarios más control y transparencia porque pueden comprender mejor qué funciones de tu app necesitan acceso a la ubicación en segundo plano.
En la figura 6, se muestra un ejemplo de una app diseñada para procesar solicitudes incrementales. Las funciones "mostrar ubicación actual" y "recomendar lugares cercanos" requieren acceso a la ubicación en primer plano. Sin embargo, solo la función "recomendar lugares cercanos" requiere acceso a la ubicación en segundo plano.
El proceso para realizar solicitudes incrementales es el siguiente:
Al principio, tu app debe guiar a los usuarios hacia las funciones que requieren acceso a la ubicación en primer plano, como la función "compartir ubicación" de la figura 1 o la función "mostrar ubicación actual" de la figura 2.
Te recomendamos inhabilitar el acceso del usuario a las funciones que requieren acceso a la ubicación en segundo plano hasta que tu app tenga acceso a la ubicación en primer plano.
Más adelante, cuando el usuario explore las funciones que requieren acceso a la ubicación en segundo plano, puedes solicitar acceso a la ubicación en segundo plano.
Recursos adicionales
Para obtener más información sobre los permisos de ubicación en Android, consulta los siguientes materiales:
Codelabs
Videos
Ejemplos
- App de ejemplo para demostrar el uso de los permisos de ubicación.