Cómo cambiar la configuración de la ubicación

Si tu app necesita solicitar la ubicación o recibir actualizaciones de permisos, el dispositivo debe tener habilitada la configuración del sistema apropiada, como la búsqueda de Wi-Fi o GPS. En lugar de habilitar directamente servicios como el GPS del dispositivo, tu app especifica el nivel requerido de consumo de energía o precisión y el intervalo de actualización deseado, y el dispositivo hace los cambios apropiados en la configuración del sistema automáticamente. El objeto de datos LocationRequest define estos parámetros de configuración.

En esta lección, aprenderás cómo usar el Cliente de configuración para verificar qué parámetros están habilitados y cómo mostrarle el diálogo "configuración de la ubicación" al usuario para que actualice su configuración con solo presionar una vez.

Cómo configurar los servicios de ubicación

A fin de usar los servicios de ubicación que proporcionan los Servicios de Google Play y el proveedor de ubicación combinada, conecta la app mediante el Cliente de configuración, luego comprueba la configuración de la ubicación de ese momento y pídele al usuario que habilite la configuración obligatoria, si es necesario.

Las apps cuyas funciones usan servicios de ubicación deben solicitar permisos de ubicación, según los casos prácticos de cada función.

Cómo configurar una solicitud de ubicación

Si deseas almacenar los parámetros de solicitudes en el proveedor de ubicación combinada, crea una LocationRequest. Los parámetros determinan el nivel de precisión de las solicitudes de ubicación. Para obtener detalles sobre todas las opciones de solicitud de ubicación disponibles, consulta la referencia de la clase LocationRequest. En esta lección, aprenderás cómo definir el intervalo de actualización, el intervalo de actualización más rápido y la prioridad, como se describe a continuación:

Intervalo de actualización
setInterval(): Este método define en milésimas de segundos la tasa a la que tu app prefiere recibir actualizaciones de ubicación. Ten en cuenta que las actualizaciones de ubicación pueden ser más rápidas o más lentas que esta tasa a fin de optimizar el uso de batería, o quizás no haya actualizaciones en absoluto (por ejemplo, si el dispositivo no tiene conectividad).
Intervalo de actualización más rápido
setFastestInterval(): Este método define en milésimas de segundos la tasa más rápida a la que tu app puede controlar las actualizaciones de ubicación. A menos que a tu app le convenga recibir actualizaciones más rápido que la tasa especificada en setInterval(), no necesitas llamar a este método.
Prioridad

setPriority(): Este método define la prioridad de la solicitud, lo que les indica a los servicios de ubicación de Servicios de Google Play qué fuentes de ubicación deben usar. Se admiten los siguientes valores:

  • PRIORITY_BALANCED_POWER_ACCURACY: Usa esta configuración para solicitar precisión de ubicación de hasta una manzana, lo que equivale a aproximadamente 100 metros. Este nivel de precisión se considera aproximado y es probable que consuma menos energía. Con esta configuración, es probable que los servicios de ubicación usen el posicionamiento de torres de telefonía celular y Wi-Fi. Sin embargo, ten en cuenta que la elección del proveedor de ubicación depende de muchos factores, por ejemplo, las fuentes que están disponibles.
  • PRIORITY_HIGH_ACCURACY: Usa esta configuración para solicitar la ubicación más precisa posible. Con esta configuración, es más probable que los servicios de ubicación usen GPS para determinar la ubicación.
  • PRIORITY_LOW_POWER: Usa esta configuración para solicitar precisión a nivel de la ciudad, lo que equivale a una precisión de aproximadamente 10 kilómetros. Este nivel de precisión se considera aproximado y es probable que consuma menos energía.
  • PRIORITY_NO_POWER: Usa esta configuración si necesitas que el impacto en el consumo de energía sea insignificante, pero deseas recibir actualizaciones de ubicación cuando estén disponibles. Con esta configuración, tu app no activa actualizaciones de ubicación, aunque sí recibe ubicaciones activadas por otras apps.

Crea la solicitud de ubicación y define los parámetros como se muestra en el siguiente código de ejemplo:

Kotlin

fun createLocationRequest() {
  val locationRequest = LocationRequest.Builder()
      .setIntervalMillis(10000)
      .setFastestIntervalMillis(5000)
      .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
      .build()
}

Java

protected void createLocationRequest() {
  LocationRequest locationRequest = LocationRequest.Builder()
      .setIntervalMillis(10000)
      .setFastestIntervalMillis(5000)
      .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
      .build();
}

La prioridad de PRIORITY_HIGH_ACCURACY, junto con la configuración de permiso de ACCESS_FINE_LOCATION que definiste en el manifiesto de la app y un intervalo de actualización rápido de 5,000 milésimas de segundos (5 segundos), permite que el proveedor de ubicación combinada muestre actualizaciones de ubicación con una precisión de hasta unos pocos metros. Este enfoque es el apropiado para mapear apps que muestran la ubicación en tiempo real.

Sugerencia de rendimiento: Si tu app accede a la red o realiza otro trabajo de ejecución prolongada después de recibir una actualización de ubicación, ajusta el intervalo más rápido a un valor inferior. Este ajuste evita que la app reciba actualizaciones que no puede usar. Cuando se complete el trabajo de ejecución prolongada, vuelve a establecer el intervalo más rápido en un valor rápido.

Cómo obtener la configuración de la ubicación actual

Una vez que te hayas conectado a los Servicios de Google Play y la API de servicios de ubicación, puedes obtener la configuración de la ubicación del dispositivo de un usuario en un determinado momento. Para ello, crea un LocationSettingsRequest.Builder y agrega una o más solicitudes de ubicación. En el siguiente fragmento de código, se muestra cómo agregar la solicitud de ubicación que se creó en el paso anterior:

Kotlin

val builder = LocationSettingsRequest.Builder()
        .addLocationRequest(locationRequest)

Java

LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
     .addLocationRequest(locationRequest);

A continuación, verifica que se cumpla la configuración de la ubicación actual:

Kotlin

val builder = LocationSettingsRequest.Builder()

// ...

val client: SettingsClient = LocationServices.getSettingsClient(this)
val task: Task<LocationSettingsResponse> = client.checkLocationSettings(builder.build())

Java

LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();

// ...

SettingsClient client = LocationServices.getSettingsClient(this);
Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());

Cuando se completa la Task, tu app puede verificar la configuración de la ubicación si observa el código de estado del objeto LocationSettingsResponse. Para obtener aún más detalles sobre el estado de la configuración de la ubicación relevante en un determinado momento, tu app puede llamar al método getLocationSettingsStates() del objeto LocationSettingsResponse.

Cómo pedirle al usuario que cambie la configuración de la ubicación

A fin de determinar si la configuración de la ubicación es apropiada para la solicitud correspondiente, agrega un OnFailureListener al objeto Task que valida la configuración de la ubicación. Luego, comprueba si el objeto Exception que se pasa al método onFailure() es una instancia de la clase ResolvableApiException, lo que indica que se debe cambiar la configuración. A continuación, muestra un diálogo en el que se le pida permiso al usuario para modificar la configuración de la ubicación mediante una llamada a startResolutionForResult().

En el siguiente fragmento de código, se muestra cómo determinar si la configuración de la ubicación del usuario permite que los servicios de ubicación creen una LocationRequest, y cómo pedirle al usuario permiso para cambiar la configuración de la ubicación, si es necesario:

Kotlin

task.addOnSuccessListener { locationSettingsResponse ->
    // All location settings are satisfied. The client can initialize
    // location requests here.
    // ...
}

task.addOnFailureListener { exception ->
    if (exception is ResolvableApiException){
        // Location settings are not satisfied, but this can be fixed
        // by showing the user a dialog.
        try {
            // Show the dialog by calling startResolutionForResult(),
            // and check the result in onActivityResult().
            exception.startResolutionForResult(this@MainActivity,
                    REQUEST_CHECK_SETTINGS)
        } catch (sendEx: IntentSender.SendIntentException) {
            // Ignore the error.
        }
    }
}

Java

task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
    @Override
    public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
        // All location settings are satisfied. The client can initialize
        // location requests here.
        // ...
    }
});

task.addOnFailureListener(this, new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        if (e instanceof ResolvableApiException) {
            // Location settings are not satisfied, but this can be fixed
            // by showing the user a dialog.
            try {
                // Show the dialog by calling startResolutionForResult(),
                // and check the result in onActivityResult().
                ResolvableApiException resolvable = (ResolvableApiException) e;
                resolvable.startResolutionForResult(MainActivity.this,
                        REQUEST_CHECK_SETTINGS);
            } catch (IntentSender.SendIntentException sendEx) {
                // Ignore the error.
            }
        }
    }
});

En la siguiente lección, Cómo recibir actualizaciones de ubicación, se muestra cómo recibir actualizaciones de ubicación periódicas.