Правильное использование информации о местоположении может быть полезным для пользователей вашего приложения. Например, если ваше приложение помогает пользователю находить дорогу во время ходьбы или вождения, или если ваше приложение отслеживает местоположение активов, ему необходимо получать местоположение устройства через регулярные интервалы. Помимо географического местоположения (широта и долгота), вы можете предоставить пользователю дополнительную информацию, такую как пеленг (горизонтальное направление движения), высоту или скорость устройства. Эта и другая информация доступна в объекте Location
, который ваше приложение может получить от поставщика объединенного местоположения . В ответ API периодически обновляет ваше приложение лучшим доступным местоположением на основе доступных в настоящее время поставщиков местоположения, таких как WiFi и GPS (глобальная система позиционирования). Точность местоположения определяется поставщиками, запрошенными вами разрешениями на местоположение и параметрами, которые вы задали в запросе местоположения.
В этом уроке показано, как запрашивать регулярные обновления о местоположении устройства с помощью метода requestLocationUpdates()
в поставщике объединенных данных о местоположении.
Получить последнее известное местоположение
Последнее известное местоположение устройства обеспечивает удобную базу для начала, гарантируя, что приложение имеет известное местоположение до начала периодических обновлений местоположения. Урок Получение последнего известного местоположения показывает, как получить последнее известное местоположение, вызвав getLastLocation()
. Фрагменты в следующих разделах предполагают, что ваше приложение уже получило последнее известное местоположение и сохранило его как объект Location
в глобальной переменной mCurrentLocation
.
Сделайте запрос местоположения
Перед запросом обновлений местоположения ваше приложение должно подключиться к службам определения местоположения и сделать запрос местоположения. Урок Изменение настроек местоположения покажет вам, как это сделать. После того, как запрос местоположения будет выполнен, вы можете начать регулярные обновления, вызвав requestLocationUpdates()
.
В зависимости от формы запроса поставщик fusion location либо вызывает метод обратного вызова 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
, используемый для отслеживания того, включил ли пользователь обновления местоположения или нет. Если пользователи отключили обновления местоположения, вы можете сообщить им о требовании местоположения вашего приложения . Подробнее о сохранении значения логического флага в разных экземплярах активности см. в разделе Сохранение состояния активности .
Определите обратный вызов обновления местоположения
Поставщик fusion location вызывает метод обратного вызова LocationCallback.onLocationResult()
. Входящий аргумент содержит объект list 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.