Изменить настройки местоположения

Если вашему приложению необходимо запрашивать местоположение или получать обновления разрешений, устройство должно включить соответствующие системные настройки, такие как GPS или сканирование Wi-Fi. Вместо прямого включения таких служб, как GPS устройства, ваше приложение указывает необходимый уровень точности/энергопотребления и желаемый интервал обновления, и устройство автоматически вносит соответствующие изменения в системные настройки. Эти настройки определяются объектом данных LocationRequest .

В этом уроке показано, как использовать клиент настроек , чтобы проверить, какие параметры включены, и отобразить диалоговое окно «Настройки местоположения», позволяющее пользователю обновить свои настройки одним касанием.

Настройка служб определения местоположения

Для использования служб определения местоположения, предоставляемых Google Play Services, и объединенного поставщика местоположения подключите ваше приложение с помощью клиента настроек , затем проверьте текущие настройки местоположения и предложите пользователю включить необходимые параметры, если это требуется.

Приложения, функции которых используют службы определения местоположения, должны запрашивать разрешения на определение местоположения в зависимости от сценариев использования этих функций.

Настройте запрос на определение местоположения.

Для хранения параметров запросов к объединенному поставщику местоположения создайте объект LocationRequest . Параметры определяют уровень точности запросов местоположения. Подробную информацию обо всех доступных параметрах запросов местоположения см. в справочнике по классу LocationRequest . В этом уроке задаются интервал обновления, самый быстрый интервал обновления и приоритет, как описано ниже:

Интервал обновления
setIntervalMillis() — Этот метод устанавливает частоту получения обновлений местоположения в миллисекундах, с которой ваше приложение предпочитает получать эти обновления. Обратите внимание, что обновления местоположения могут происходить несколько быстрее или медленнее, чем указано, для оптимизации расхода заряда батареи, или же обновления могут отсутствовать вовсе (например, если устройство не имеет подключения к сети).
Самый быстрый интервал обновления
setMinUpdateIntervalMillis() — Этот метод устанавливает максимальную скорость обработки обновлений местоположения в миллисекундах, указанную в методе setInterval(). Если вашему приложению не требуется получать обновления быстрее, чем указано в setInterval() , вызывать этот метод не нужно.
Приоритет

setPriority() — Этот метод устанавливает приоритет запроса, что дает службам определения местоположения Google Play важную подсказку о том, какие источники местоположения следует использовать. Поддерживаются следующие значения:

  • PRIORITY_BALANCED_POWER_ACCURACY — Используйте этот параметр для запроса точности определения местоположения в пределах одного городского квартала, что составляет приблизительно 100 метров. Это считается приблизительным уровнем точности и, вероятно, потребует меньше энергии. При этом параметре службы определения местоположения, скорее всего, будут использовать позиционирование по Wi-Fi и сотовым вышкам. Однако следует отметить, что выбор поставщика данных о местоположении зависит от многих других факторов, таких как доступные источники.
  • PRIORITY_HIGH_ACCURACY — Используйте этот параметр, чтобы запросить максимально точное местоположение. При таком значении службы определения местоположения с большей вероятностью будут использовать GPS для определения местоположения.
  • PRIORITY_LOW_POWER — Используйте этот параметр для запроса точности на уровне города, что составляет приблизительно 10 километров. Это считается приблизительной точностью и, вероятно, потребует меньше энергии.
  • PRIORITY_PASSIVE — Используйте этот параметр, если вам необходимо минимальное влияние на энергопотребление, но вы хотите получать обновления местоположения, когда они становятся доступны. При этом параметре ваше приложение не будет запускать обновления местоположения, но будет получать данные о местоположении, запускаемые другими приложениями.

Создайте запрос на определение местоположения и задайте параметры, как показано в этом примере кода:

Котлин

  fun createLocationRequest() {
    val locationRequest = LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 10000)
        .setMinUpdateIntervalMillis(5000)
        .build()
}

Java

  protected void createLocationRequest() {
    LocationRequest locationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 10000)
            .setMinUpdateIntervalMillis(5000)
            .build();
}

Приоритет PRIORITY_HIGH_ACCURACY в сочетании с параметром разрешения ACCESS_FINE_LOCATION , определенным в манифесте приложения, и быстрым интервалом обновления в 5000 миллисекунд (5 секунд) приводит к тому, что объединенный поставщик данных о местоположении возвращает обновления местоположения с точностью до нескольких футов. Такой подход подходит для картографических приложений, отображающих местоположение в реальном времени.

Совет по производительности: если ваше приложение обращается к сети или выполняет другую длительную работу после получения обновления местоположения, уменьшите самый быстрый интервал до более медленного значения. Эта настройка предотвратит получение приложением обновлений, которые оно не сможет использовать. После завершения длительной работы верните самый быстрый интервал к быстрому значению.

Получить настройки текущего местоположения

После подключения к сервисам Google Play и API служб определения местоположения вы можете получить текущие настройки местоположения устройства пользователя. Для этого создайте объект LocationSettingsRequest.Builder и добавьте один или несколько запросов на определение местоположения. Следующий фрагмент кода показывает, как добавить запрос на определение местоположения, созданный на предыдущем шаге:

Котлин

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

Java

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

Далее проверьте, соответствуют ли текущие настройки местоположения требованиям:

Котлин

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());

После завершения Task ваше приложение может проверить настройки местоположения, просмотрев код состояния объекта LocationSettingsResponse . Чтобы получить еще более подробную информацию о текущем состоянии соответствующих настроек местоположения, ваше приложение может вызвать метод getLocationSettingsStates() объекта LocationSettingsResponse .

Предложите пользователю изменить настройки местоположения.

Чтобы определить, соответствуют ли настройки местоположения запросу, добавьте в объект Task обработчик OnFailureListener , который проверяет настройки местоположения. Затем проверьте, является ли объект Exception переданный в метод onFailure() экземпляром класса ResolvableApiException , что указывает на необходимость изменения настроек. После этого отобразите диалоговое окно, запрашивающее у пользователя разрешение на изменение настроек местоположения, вызвав startResolutionForResult() .

Приведенный ниже фрагмент кода показывает, как определить, позволяют ли настройки местоположения пользователя службам определения местоположения создавать объект LocationRequest , а также как запросить у пользователя разрешение на изменение настроек местоположения, если это необходимо:

Котлин

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

В следующем уроке, «Запрос на обновление местоположения» , вы узнаете, как получать периодические обновления местоположения.