Правильное использование информации о местоположении может быть полезным для пользователей вашего приложения. Например, если ваше приложение помогает пользователю найти дорогу во время ходьбы или вождения, или если ваше приложение отслеживает местоположение активов, ему необходимо получать данные о местоположении устройства через регулярные интервалы. Помимо географического местоположения (широты и долготы), вы можете захотеть предоставить пользователю дополнительную информацию, такую как пеленг (горизонтальное направление движения), высоту или скорость устройства. Эта и другая информация доступна в объекте Location
, который ваше приложение может получить от поставщика объединённого местоположения . В ответ API периодически обновляет ваше приложение, предоставляя наилучшее доступное местоположение на основе доступных в данный момент поставщиков местоположения, таких как Wi-Fi и GPS (глобальная система позиционирования). Точность местоположения определяется поставщиками, запрошенными вами разрешениями на местоположение и параметрами, указанными вами в запросе местоположения.
В этом уроке показано, как запрашивать регулярные обновления о местоположении устройства с помощью метода requestLocationUpdates()
в поставщике объединенного местоположения.
Получить последнее известное местоположение
Последнее известное местоположение устройства служит удобной отправной точкой, гарантируя, что приложение будет знать местоположение до начала периодического обновления данных. В уроке « Получение последнего известного местоположения» показано, как получить последнее известное местоположение с помощью метода getLastLocation()
. В следующих разделах предполагается, что ваше приложение уже получило последнее известное местоположение и сохранило его как объект Location
в глобальной переменной mCurrentLocation
.
Сделать запрос местоположения
Прежде чем запрашивать обновления местоположения, ваше приложение должно подключиться к службам геолокации и выполнить запрос. Урок « Изменение настроек местоположения» покажет вам, как это сделать. После того, как запрос местоположения будет настроен, вы можете запустить регулярные обновления, вызвав функцию requestLocationUpdates()
.
В зависимости от формы запроса, поставщик объединённого местоположения либо вызывает метод обратного вызова LocationCallback.onLocationResult()
и передаёт ему список объектов Location
, либо выдаёт PendingIntent
, содержащий местоположение в своих расширенных данных. Точность и частота обновлений зависят от запрошенных вами разрешений на доступ к местоположению и параметров, заданных в объекте запроса местоположения.
В этом уроке показано, как получить обновление, используя метод обратного вызова LocationCallback
. Вызовите метод requestLocationUpdates()
, передав ему экземпляр объекта LocationRequest
и метод LocationCallback
. Определите метод startLocationUpdates()
, как показано в следующем примере кода:
Котлин
override fun onResume() { super.onResume() if (requestingLocationUpdates) startLocationUpdates() } private fun startLocationUpdates() { fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()) }
Ява
@Override protected void onResume() { super.onResume(); if (requestingLocationUpdates) { startLocationUpdates(); } } private void startLocationUpdates() { fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()); }
Обратите внимание, что приведённый выше фрагмент кода ссылается на логический флаг requestingLocationUpdates
, который используется для отслеживания того, включил ли пользователь обновления местоположения. Если пользователи отключили обновления местоположения, вы можете сообщить им о требовании вашего приложения к местоположению . Подробнее о сохранении значения логического флага между экземплярами Activity см. в разделе Сохранение состояния Activity .
Определить обратный вызов обновления местоположения
Поставщик объединённого местоположения вызывает метод обратного вызова LocationCallback.onLocationResult()
. Входящий аргумент содержит список объектов Location
, содержащий широту и долготу местоположения. В следующем фрагменте кода показано, как реализовать интерфейс LocationCallback
и определить метод, а затем получить временную метку обновления местоположения и отобразить широту, долготу и временную метку в пользовательском интерфейсе приложения:
Котлин
private lateinit var locationCallback: LocationCallback // ... override fun onCreate(savedInstanceState: Bundle?) { // ... locationCallback = object : LocationCallback() { override fun onLocationResult(locationResult: LocationResult?) { locationResult ?: return for (location in locationResult.locations){ // Update UI with location data // ... } } } }
Ява
private LocationCallback locationCallback; // ... @Override protected void onCreate(Bundle savedInstanceState) { // ... locationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { if (locationResult == null) { return; } for (Location location : locationResult.getLocations()) { // Update UI with location data // ... } } }; }
Остановить обновления местоположения
Подумайте, нужно ли останавливать обновления местоположения, когда активность больше не активна, например, когда пользователь переключается в другое приложение или на другую активность в том же приложении. Это может быть полезно для снижения энергопотребления, при условии, что приложению не нужно собирать информацию, даже работая в фоновом режиме. В этом разделе показано, как остановить обновления в методе onPause()
активности.
Чтобы остановить обновления местоположения, вызовите removeLocationUpdates()
, передав ему LocationCallback
, как показано в следующем примере кода:
Котлин
override fun onPause() { super.onPause() stopLocationUpdates() } private fun stopLocationUpdates() { fusedLocationClient.removeLocationUpdates(locationCallback) }
Ява
@Override protected void onPause() { super.onPause(); stopLocationUpdates(); } private void stopLocationUpdates() { fusedLocationClient.removeLocationUpdates(locationCallback); }
Используйте логическое значение requestingLocationUpdates
для отслеживания того, включены ли в данный момент обновления местоположения. В методе onResume()
активности проверьте, активны ли в данный момент обновления местоположения, и активируйте их, если нет:
Котлин
override fun onResume() { super.onResume() if (requestingLocationUpdates) startLocationUpdates() }
Ява
@Override protected void onResume() { super.onResume(); if (requestingLocationUpdates) { startLocationUpdates(); } }
Сохранить состояние активности
Изменение конфигурации устройства, например, изменение ориентации экрана или языка, может привести к уничтожению текущей активности. Поэтому ваше приложение должно хранить всю информацию, необходимую для повторного создания активности. Один из способов сделать это — использовать состояние экземпляра, хранящееся в объекте Bundle
.
В следующем примере кода показано, как использовать обратный вызов onSaveInstanceState()
действия для сохранения состояния экземпляра:
Котлин
override fun onSaveInstanceState(outState: Bundle?) { outState?.putBoolean(REQUESTING_LOCATION_UPDATES_KEY, requestingLocationUpdates) super.onSaveInstanceState(outState) }
Ява
@Override protected void onSaveInstanceState(Bundle outState) { outState.putBoolean(REQUESTING_LOCATION_UPDATES_KEY, requestingLocationUpdates); // ... super.onSaveInstanceState(outState); }
Определите метод updateValuesFromBundle()
для восстановления сохранённых значений из предыдущего экземпляра активности, если они доступны. Вызовите этот метод из метода onCreate()
активности, как показано в следующем примере кода:
Котлин
override fun onCreate(savedInstanceState: Bundle?) { // ... updateValuesFromBundle(savedInstanceState) } private fun updateValuesFromBundle(savedInstanceState: Bundle?) { savedInstanceState ?: return // Update the value of requestingLocationUpdates from the Bundle. if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) { requestingLocationUpdates = savedInstanceState.getBoolean( REQUESTING_LOCATION_UPDATES_KEY) } // ... // Update UI to match restored state updateUI() }
Ява
@Override public void onCreate(Bundle savedInstanceState) { // ... updateValuesFromBundle(savedInstanceState); } private void updateValuesFromBundle(Bundle savedInstanceState) { if (savedInstanceState == null) { return; } // Update the value of requestingLocationUpdates from the Bundle. if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) { requestingLocationUpdates = savedInstanceState.getBoolean( REQUESTING_LOCATION_UPDATES_KEY); } // ... // Update UI to match restored state updateUI(); }
Дополнительную информацию о сохранении состояния экземпляра см. в справочнике по классу Android Activity .
Примечание: Для более надёжного хранения вы можете хранить пользовательские настройки в SharedPreferences
вашего приложения. Установите общую настройку в методе onPause()
вашей активности и извлеките её в onResume()
. Подробнее о сохранении настроек см. в статье Сохранение наборов «ключ-значение» .
Дополнительные ресурсы
Чтобы узнать больше, воспользуйтесь следующими ресурсами:
Образцы
- Пример приложения для демонстрации получения обновлений местоположения на Android.