Solicita permisos de ubicación

Para proteger la privacidad del usuario, las apps que usan servicios de ubicación deben solicitar los permisos correspondientes.

Cuando solicites permisos de ubicación, sigue las mismas prácticas recomendadas que para cualquier otro permiso de tiempo de ejecución. Una diferencia importante cuando se trata de permisos de ubicación es que el sistema incluye varios permisos relacionados con la ubicación. Los permisos que solicites y el modo en que los solicites dependerán de los requisitos de ubicación del caso de uso de tu app.

En esta página, se describen los diferentes tipos de requisitos de ubicación y se proporciona orientación para solicitar permisos de ubicación en cada caso.

Tipos de acceso a la ubicación

Cada permiso tiene una combinación de las siguientes características:

Ubicación en primer plano

Si tu app contiene una función que comparte o recibe información de ubicación solo una vez o durante un tiempo definido, esa función requiere acceso a la ubicación en primer plano. Estos son algunos ejemplos:

  • Dentro de una app de navegación, una función permite a los usuarios obtener instrucciones paso a paso.
  • Dentro de una app de mensajería, una función permite a los usuarios compartir su ubicación actual con otro usuario.

El sistema considera que tu app usa la ubicación en primer plano si una función accede a la ubicación actual del dispositivo en una de las siguientes situaciones:

  • Una actividad que pertenece a tu app es visible.
  • Tu app ejecuta un servicio en primer plano. Cuando se ejecuta un servicio en primer plano, el sistema muestra una notificación persistente para atraer la atención del usuario. Tu app conserva el acceso cuando se coloca en segundo plano, por ejemplo, cuando el usuario presiona el botón Inicio en su dispositivo o apaga la pantalla.

    Además, se recomienda que declares un tipo de servicio en primer plano de location, como se muestra en el siguiente fragmento de código. En Android 10 (nivel de API 29) y versiones posteriores, debes declarar este tipo de servicio en primer plano.

    <!-- Recommended for Android 9 (API level 28) and lower. -->
    <!-- Required for Android 10 (API level 29) and higher. -->
    <service
        android:name="MyNavigationService"
        android:foregroundServiceType="location" ... >
        <!-- Any inner elements would go here. -->
    </service>

Declaras la necesidad de una ubicación en primer plano cuando tu app solicita los permisos ACCESS_COARSE_LOCATION o ACCESS_FINE_LOCATION, como se muestra en el siguiente fragmento:

<manifest ... >
  <!-- Always include this permission -->
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

  <!-- Include only if your app benefits from precise location access. -->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>

Ubicación en segundo plano

Una app requiere acceso a la ubicación en segundo plano si una función dentro de la app comparte constantemente la ubicación con otros usuarios o usa la API de geovallado. Entre los ejemplos, se incluyen los siguientes:

  • Dentro de una app familiar para compartir la ubicación, una función permite que los usuarios compartan la ubicación de forma continua con los miembros de la familia.
  • Dentro de una app de IoT, una función permite al usuario configurar sus dispositivos para la casa de modo que se apaguen cuando el usuario salga de su casa y se vuelvan a activar cuando regrese.

El sistema considera que tu app usa la ubicación en segundo plano si accede a la ubicación actual del dispositivo en una situación diferente de la descrita en la sección Ubicación en primer plano. La precisión de la ubicación en segundo plano es la misma que la precisión de la ubicación en primer plano, que depende de los permisos de ubicación que declare tu app.

En Android 10 (nivel de API 29) y versiones posteriores, debes declarar el permiso ACCESS_BACKGROUND_LOCATION en el manifiesto de tu app para solicitar acceso a la ubicación en segundo plano durante el tiempo de ejecución. En las versiones anteriores de Android, cuando tu app recibe acceso a la ubicación en primer plano, también recibe automáticamente acceso a la ubicación en segundo plano.

<manifest ... >
  <!-- Required only when requesting background location access on
       Android 10 (API level 29) and higher. -->
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>

Exactitud

Android admite los siguientes niveles de precisión de la ubicación:

Aproximada
Proporciona una estimación de la ubicación del dispositivo. Si esta estimación de la ubicación es de LocationManagerService o FusedLocationProvider, la estimación es exacta en un radio de 3 kilómetros cuadrados (aproximadamente, 1.2 millas cuadradas). Tu app puede recibir ubicaciones con este nivel de precisión cuando declaras el permiso ACCESS_COARSE_LOCATION, pero no el permiso ACCESS_FINE_LOCATION.
Precisa
Proporciona una estimación de la ubicación del dispositivo que sea lo más precisa posible. Si la estimación de la ubicación es de LocationManagerService o FusedLocationProvider, suele ser de 50 metros (160 pies) y, a veces, tan precisa como de unos pocos metros (10 pies) o mejor. Tu app puede recibir ubicaciones en este nivel de precisión cuando declaras el permiso ACCESS_FINE_LOCATION.

Si el usuario otorga el permiso de ubicación aproximada, tu app solo tendrá acceso a la ubicación aproximada, independientemente de los permisos de ubicación que declare.

Tu app debería funcionar cuando el usuario solo otorgue acceso a la ubicación aproximada. Si una función de tu app requiere acceso a una ubicación precisa con el permiso ACCESS_FINE_LOCATION, puedes pedirle al usuario que permita que tu app acceda a la ubicación precisa.

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 solamente 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 elegir durante cuánto tiempo se otorga el 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

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.
locationPermissionRequest.launch(arrayOf(
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.ACCESS_COARSE_LOCATION))

Java

ActivityResultLauncher<String[]> locationPermissionRequest =
    registerForActivityResult(new ActivityResultContracts
        .RequestMultiplePermissions(), result -> {
            Boolean fineLocationGranted = result.getOrDefault(
                    Manifest.permission.ACCESS_FINE_LOCATION, false);
            Boolean 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 la figura 4 y la figura 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 la función que requiere acceso a la ubicación en segundo plano, podrás solicitar acceso a la ubicación en segundo plano.

Solicita la ubicación en segundo plano si es necesario

Figura 7: La página de configuración incluye una opción llamada Permitir todo el tiempo (Allow all the time), que otorga acceso a la ubicación en segundo plano.

El contenido del diálogo de los permisos depende de la versión del SDK de destino

Cuando una función de tu app solicita la ubicación en segundo plano, en un dispositivo que ejecuta Android 10 (nivel de API 29), el diálogo de permisos del sistema incluye una opción llamada Permitir todo el tiempo (Allow all the time). Si el usuario selecciona esta opción, la función en tu app obtiene acceso a la ubicación en segundo plano.

Sin embargo, en Android 11 (nivel de API 30) y versiones posteriores, el diálogo del sistema no incluye la opción Permitir todo el tiempo (Allow all the time). En su lugar, los usuarios deben habilitar la ubicación en segundo plano, en una página de configuración, como se muestra en la Figura 7.

Puedes ayudar a los usuarios a navegar hasta esa página de configuración siguiendo las prácticas recomendadas cuando solicites el permiso de acceso a la ubicación en segundo plano. El proceso para otorgar el permiso depende de la versión del SDK de destino de tu app.

La app está orientada a Android 11 o versiones posteriores

Si no se le otorgó el permiso ACCESS_BACKGROUND_LOCATION a tu app, y el objeto shouldShowRequestPermissionRationale() muestra el elemento true, enséñales a los usuarios una IU educativa que incluya lo siguiente:

  • Una explicación clara de por qué la función de tu app requiere acceso a la ubicación en segundo plano.
  • La etiqueta visible para el usuario de la opción de configuración que otorga la ubicación en segundo plano (por ejemplo, Permitir todo el tiempo (Allow all the time) en la figura 7), que puede obtenerse llamando al método getBackgroundPermissionOptionLabel(). El valor que se muestra de este método se localiza según la preferencia de idioma del dispositivo del usuario.
  • Una opción para que los usuarios rechacen el permiso. Si los usuarios rechazan el acceso a la ubicación en segundo plano, deberían poder seguir usando tu app.
Los usuarios pueden presionar la notificación del sistema para cambiar la configuración de la ubicación de una app.
Figura 8: Notificación que le recuerda al usuario que le otorgó a una app acceso a la ubicación en segundo plano.

La app está orientada a Android 10 o versiones anteriores

Cuando una función de tu app solicita acceso a la ubicación en segundo plano, los usuarios ven un diálogo del sistema. Este cuadro de diálogo incluye una opción para navegar hasta las opciones de permisos de ubicación de tu app en una página de configuración.

Siempre que tu app ya siga las prácticas recomendadas de solicitud de permisos de ubicación, no es necesario que hagas ningún cambio para admitir este comportamiento.

El usuario puede afectar la precisión de la ubicación en segundo plano

Si el usuario solicita la ubicación aproximada, las opciones del usuario en el diálogo de permisos de ubicación también se aplican a la ubicación en segundo plano. En otras palabras, si el usuario le otorga el permiso ACCESS_BACKGROUND_LOCATION a la app, pero brinda acceso solo a la ubicación aproximada en primer plano, la app también tendrá acceso solo a la ubicación aproximada en segundo plano.

Recordatorio de acceso a la ubicación en segundo plano

En Android 10 y versiones posteriores, cuando una función de tu app accede a la ubicación del dispositivo en segundo plano después de que el usuario otorga ese acceso, el sistema programa el envío de una notificación al usuario para recordarle que le otorgó a tu app acceso a la ubicación del dispositivo en todo momento. En la figura 8, se muestra una notificación de ejemplo.

Cómo verificar los requisitos de ubicación en las dependencias del SDK de la app

Verifica si tu app usa algún SDK que dependa de los permisos de ubicación, especialmente ACCESS_FINE_LOCATION. Consulta este artículo en Medium sobre los comportamientos de las dependencias del SDK.

Recursos adicionales

Para obtener más información sobre los permisos de ubicación en Android, consulta los siguientes materiales:

Codelabs

Videos

Ejemplos