Odpowiednie wykorzystanie informacji o lokalizacji może być korzystne dla użytkowników Twojej aplikacji. Jeśli na przykład aplikacja pomaga użytkownikowi w znalezieniu drogi podczas spaceru lub jazdy samochodem albo śledzi lokalizację zasobów, musi regularnie uzyskiwać lokalizację urządzenia. Oprócz lokalizacji geograficznej (szerokości i długości geograficznej) możesz podać użytkownikowi dodatkowe informacje, takie jak kierunek (poziomy kierunek podróży), wysokość lub prędkość urządzenia. Te i inne informacje są dostępne w obiekcie Location
, który aplikacja może pobrać od dostawcy uśrednionej lokalizacji. W odpowiedzi interfejs API okresowo aktualizuje aplikację, podając najlepszą dostępną lokalizację na podstawie aktualnie dostępnych dostawców lokalizacji, takich jak Wi-Fi i GPS (Global Positioning System). Dokładność lokalizacji zależy od dostawców, uprawnień do lokalizacji, o które prosisz, oraz opcji ustawionych w żądaniu lokalizacji.
Z tej lekcji dowiesz się, jak za pomocą metody requestLocationUpdates()
w usłudze lokalizacji zintegrowanej wysyłać prośby o regularne aktualizacje lokalizacji urządzenia.
Pobieranie ostatniej znanej lokalizacji
Ostatnia znana lokalizacja urządzenia stanowi wygodną bazę, od której można zacząć, dzięki czemu aplikacja ma znaną lokalizację przed rozpoczęciem okresowych aktualizacji lokalizacji. Lekcja Uzyskiwanie ostatniej znanej lokalizacji pokazuje, jak uzyskać ostatnią znaną lokalizację, wywołując getLastLocation()
.
Fragmenty kodu w sekcjach poniżej zakładają, że aplikacja pobrała już ostatnią znaną lokalizację i zapisała ją jako obiekt Location
w zmiennej globalnej mCurrentLocation
.
Wysyłanie prośby o lokalizację
Zanim aplikacja poprosi o aktualizacje lokalizacji, musi połączyć się z usługami lokalizacyjnymi i wysłać żądanie lokalizacji. W lekcji Zmiana ustawień lokalizacji dowiesz się, jak to zrobić. Po przesłaniu prośby o lokalizację możesz rozpocząć regularne aktualizacje, wywołując funkcję requestLocationUpdates()
.
W zależności od formy żądania dostawca połączonej lokalizacji wywołuje metodę wywołania zwrotnego LocationCallback.onLocationResult()
i przekazuje jej listę obiektów Location
lub wysyła PendingIntent
, które zawiera lokalizację w danych rozszerzonych. Dokładność i częstotliwość aktualizacji zależą od zezwoleń na lokalizację, o które prosisz, oraz od opcji ustawionych w obiekcie żądania lokalizacji.
Z tej lekcji dowiesz się, jak uzyskać aktualizację za pomocą wywołania zwrotnego LocationCallback
. Wywołaj funkcję requestLocationUpdates()
, przekazując jej instancję obiektu LocationRequest
i wartość LocationCallback
.
Zdefiniuj metodę startLocationUpdates()
, jak pokazano w tym przykładzie kodu:
Kotlin
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()); }
Zwróć uwagę, że powyższy fragment kodu odwołuje się do flagi logicznej requestingLocationUpdates
, która służy do śledzenia, czy użytkownik włączył lub wyłączył aktualizacje lokalizacji. Jeśli użytkownicy wyłączyli aktualizacje lokalizacji, możesz poinformować ich o wymaganiach aplikacji dotyczących lokalizacji. Więcej informacji o zachowywaniu wartości flagi logicznej w różnych instancjach aktywności znajdziesz w artykule Zapisywanie stanu aktywności.
Zdefiniuj wywołanie zwrotne aktualizacji lokalizacji
Dostawca uśrednionej lokalizacji wywołuje metodę wywołania zwrotnego LocationCallback.onLocationResult()
. Argument przychodzący zawiera listę Location
zawierającą szerokość i długość geograficzną lokalizacji. Poniższy fragment kodu pokazuje, jak zaimplementować interfejs LocationCallback
i zdefiniować metodę, a następnie uzyskać sygnaturę czasową aktualizacji lokalizacji i wyświetlić szerokość i długość geograficzną oraz sygnaturę czasową w interfejsie użytkownika aplikacji:
Kotlin
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 // ... } } }; }
Zatrzymywanie aktualizacji lokalizacji
Zastanów się, czy chcesz zatrzymać aktualizacje lokalizacji, gdy aktywność nie jest już w centrum uwagi, np. gdy użytkownik przełączy się na inną aplikację lub na inne działanie w tej samej aplikacji. Może to być przydatne do zmniejszenia zużycia energii, pod warunkiem że aplikacja nie musi zbierać informacji nawet wtedy, gdy działa w tle. W tej sekcji dowiesz się, jak zatrzymać aktualizacje w metodzie onPause()
aktywności.
Aby zatrzymać aktualizacje lokalizacji, wywołaj funkcję removeLocationUpdates()
, przekazując jej wartość LocationCallback
, jak pokazano w tym przykładowym kodzie:
Kotlin
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); }
Użyj wartości logicznej requestingLocationUpdates
, aby śledzić, czy aktualizacje lokalizacji są obecnie włączone. W metodzie onResume()
działania sprawdź, czy aktualizacje lokalizacji są obecnie aktywne, i w razie potrzeby je aktywuj:
Kotlin
override fun onResume() { super.onResume() if (requestingLocationUpdates) startLocationUpdates() }
Java
@Override protected void onResume() { super.onResume(); if (requestingLocationUpdates) { startLocationUpdates(); } }
Zapisywanie stanu aktywności
Zmiana konfiguracji urządzenia, np. orientacji ekranu lub języka, może spowodować zniszczenie bieżącej aktywności. Dlatego aplikacja musi przechowywać wszystkie informacje potrzebne do ponownego utworzenia aktywności.
Można to zrobić za pomocą stanu instancji przechowywanego w obiekcie Bundle
.
Poniższy przykładowy kod pokazuje, jak użyć wywołania zwrotnego onSaveInstanceState()
aktywności, aby zapisać stan instancji:
Kotlin
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); }
Zdefiniuj metodę updateValuesFromBundle()
, która przywróci zapisane wartości z poprzedniej instancji aktywności, jeśli są dostępne. Wywołaj metodę z metody onCreate()
aktywności, jak pokazano w tym przykładowym kodzie:
Kotlin
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(); }
Więcej informacji o zapisywaniu stanu instancji znajdziesz w dokumentacji klasy Android Activity.
Uwaga: aby zapewnić trwalsze przechowywanie, możesz zapisać preferencje użytkownika w SharedPreferences
aplikacji. Ustaw preferencje udostępniania w metodzie onPause()
aktywności i pobierz preferencje w metodzie onResume()
.
Więcej informacji o zapisywaniu ustawień znajdziesz w artykule Zapisywanie zestawów par klucz-wartość.
Dodatkowe materiały
Więcej informacji znajdziesz w tych materiałach:
Próbki
- Przykładowa aplikacja, która pokazuje, jak otrzymywać aktualizacje lokalizacji na Androidzie.