Правильное использование информации о местоположении может быть полезно для пользователей вашего приложения. Например, если ваше приложение помогает пользователю ориентироваться во время ходьбы или вождения, или если ваше приложение отслеживает местоположение объектов, ему необходимо регулярно получать местоположение устройства. Помимо географического местоположения (широта и долгота), вы можете предоставить пользователю дополнительную информацию, такую как азимут (горизонтальное направление движения), высота или скорость устройства. Эта и другая информация доступна в объекте 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()) }
Java
@Override protected void onResume() { super.onResume(); if (requestingLocationUpdates) { startLocationUpdates(); } } private void startLocationUpdates() { fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()); }
Обратите внимание, что приведенный выше фрагмент кода ссылается на логический флаг requestingLocationUpdates , используемый для отслеживания того, включил или выключил пользователь обновления местоположения. Если пользователи отключили обновления местоположения, вы можете сообщить им о требовании вашего приложения к данным о местоположении . Более подробную информацию о сохранении значения логического флага между экземплярами активности см. в разделе «Сохранение состояния активности» .
Определите функцию обратного вызова для обновления местоположения.
Объединенный поставщик местоположения вызывает метод обратного вызова 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 // ... } } } }
Java
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) }
Java
@Override protected void onPause() { super.onPause(); stopLocationUpdates(); } private void stopLocationUpdates() { fusedLocationClient.removeLocationUpdates(locationCallback); }
Используйте логическую переменную ` requestingLocationUpdates , чтобы отслеживать, включены ли в данный момент обновления местоположения. В методе ` onResume() активности проверьте, активны ли в данный момент обновления местоположения, и активируйте их, если нет:
Котлин
override fun onResume() { super.onResume() if (requestingLocationUpdates) startLocationUpdates() }
Java
@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) }
Java
@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() }
Java
@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(); }
Для получения более подробной информации о сохранении состояния экземпляра см. справочник по классу Activity в Android .
Примечание: Для более надежного хранения вы можете сохранить пользовательские настройки в SharedPreferences вашего приложения. Установите общие настройки в методе onPause() вашего Activity и получите их в onResume() . Для получения дополнительной информации о сохранении настроек см. раздел «Сохранение наборов ключ-значение» .
Дополнительные ресурсы
Для получения более подробной информации воспользуйтесь следующими ресурсами:
Образцы
- Пример приложения , демонстрирующий получение обновлений местоположения в Android.