Solicita acceso a la ubicación en el tiempo de ejecución

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).

Después de que el usuario selecciona el botón Compartir ubicación (Share Location), aparece el diálogo de permiso de ubicación del sistema.
Figura 1: Función Compartir ubicación que requiere acceso a la ubicación en primer plano. La función está habilitada si el usuario selecciona Permitir solo con la app en uso.

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.

El diálogo solo hace referencia a la ubicación aproximada y contiene 3 botones, uno encima del otro.
Figura 2: Diálogo de permisos del sistema que aparece cuando la app solo solicita ACCESS_COARSE_LOCATION.
El diálogo tiene 2 conjuntos de opciones, uno encima del otro
Figura 3: Diálogo de permisos del sistema que aparece cuando tu app solicita ACCESS_FINE_LOCATION y ACCESS_COARSE_LOCATION en una sola solicitud de tiempo de ejecución.

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:

  1. Si es necesario, explica el motivo por el que la app necesita el permiso.
  2. Vuelve a solicitar juntos los permisos ACCESS_FINE_LOCATION y ACCESS_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:
El diálogo incluye las opciones &quot;Cambiar a ubicación precisa&quot; (Change to precise location), &quot;Solo esta vez&quot; (Only this time) y &quot;Denegar (Deny)&quot;.
Figura 4: Anteriormente, el usuario seleccionaba Aproximada y Mientras la app está en uso (While using the app), en el diálogo de la figura 3.
El diálogo incluye las opciones &quot;Solo esta vez&quot; (Only this time) y &quot;Denegar&quot; (Deny)
Figura 5: Anteriormente, el usuario seleccionaba Aproximada y Solo esta vez (Only this time), en el diálogo de la figura 3.

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 botón que habilita el acceso a la ubicación en primer plano se encuentra a una distancia de media pantalla con respecto al botón que habilita la ubicación en segundo plano.
Figura 6: Ambas funciones requieren acceso a la ubicación, pero 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:

  1. 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.

  2. 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