Poproś o aktualizacje lokalizacji

Odpowiednie wykorzystanie informacji o lokalizacji może być korzystne dla użytkowników aplikacji. Jeśli na przykład aplikacja pomaga użytkownikowi znaleźć drogę podczas spaceru lub jazdy albo śledzi lokalizację zasobów, musi regularnie uzyskiwać informacje o lokalizacji urządzenia. Oprócz położenia geograficznego (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 danych od dostępnych dostawców lokalizacji, takich jak Wi-Fi i GPS (Global Positioning System). Dokładność lokalizacji zależy od dostawców, uprawnień dostępu do lokalizacji, o które prosisz, oraz opcji ustawionych w żądaniu lokalizacji.

Z tej lekcji dowiesz się, jak prosić o regularne aktualizacje lokalizacji urządzenia za pomocą metody requestLocationUpdates() w dostawcy uśrednionej lokalizacji.

Sprawdzanie ostatniej znanej lokalizacji

Ostatnia znana lokalizacja urządzenia stanowi przydatną podstawę do rozpoczęcia, dzięki czemu aplikacja ma znaną lokalizację przed rozpoczęciem okresowych informacji o zmianie lokalizacji. Z lekcji Pobieranie ostatniej znanej lokalizacji dowiesz się, jak pobrać ostatnią znaną lokalizację, wywołując metodę getLastLocation(). We fragmentach kodu w następnych sekcjach zakładamy, ż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 będzie mogła poprosić o informacje o zmianie lokalizacji, musi połączyć się z usługami lokalizacyjnymi i wysłać żądanie lokalizacji. Jak to zrobić, dowiesz się z lekcji Zmienianie ustawień lokalizacji. Po wysłaniu prośby o lokalizację możesz zacząć regularnie aktualizować dane, wywołując metodę requestLocationUpdates().

W zależności od formy żądania dostawca uśrednionej lokalizacji wywołuje metodę wywołania zwrotnego LocationCallback.onLocationResult() i przekazuje jej listę obiektów Location lub wysyła obiekt PendingIntent, który zawiera lokalizację w rozszerzonych danych. Na dokładność i częstotliwość aktualizacji mają wpływ uprawnienia dostępu do lokalizacji, o które prosisz, oraz opcje ustawione w obiekcie żądania lokalizacji.

Z tej lekcji dowiesz się, jak uzyskać aktualizację za pomocą metody wywołania zwrotnego LocationCallback. Wywołaj requestLocationUpdates(), przekazując instancję obiektu LocationRequest i LocationCallback. Zdefiniuj metodę startLocationUpdates(), jak pokazano w tym przykładowym kodzie:

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

Zauważ, że powyższy fragment kodu odnosi 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 instancjach aktywności znajdziesz w artykule Zapisywanie stanu aktywności.

Definiowanie wywołania zwrotnego informacji o zmianie lokalizacji

Dostawca uśrednionej lokalizacji wywołuje metodę wywołania zwrotnego LocationCallback.onLocationResult(). Argument przychodzący zawiera obiekt listy Location z szerokością i długością geograficzną lokalizacji. Poniższy fragment kodu pokazuje, jak wdrożyć interfejs LocationCallback i zdefiniować metodę, a następnie uzyskać sygnaturę czasową informacji o zmianie lokalizacji i wyświetlić szerokość i długość geograficzną oraz sygnaturę czasową w interfejsie 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 informacji o zmianie lokalizacji

Zastanów się, czy chcesz zatrzymać aktualizacje lokalizacji, gdy aktywność nie jest już aktywna, np. gdy użytkownik przełączy się na inną aplikację lub inną aktywność w tej samej aplikacji. Może to być przydatne do zmniejszenia zużycia energii, pod warunkiem że aplikacja nie musi zbierać informacji, nawet gdy działa w tle. W tej sekcji dowiesz się, jak zatrzymać aktualizacje w metodzie onPause() aktywności.

Aby zatrzymać informację o zmianie lokalizacji, wywołaj metodę removeLocationUpdates(), przekazując jej obiekt 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 informacje o zmianie lokalizacji są obecnie włączone. W metodzie onResume() aktywności sprawdź, czy informacje o zmianie lokalizacji są obecnie aktywne, a jeśli nie, aktywuj je:

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. zmiana orientacji ekranu lub języka, może spowodować zniszczenie bieżącej aktywności. Dlatego aplikacja musi przechowywać wszystkie informacje potrzebne do odtworzenia aktywności. Jednym ze sposobów jest użycie 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(), aby 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ć bardziej trwałe przechowywanie, możesz zapisać preferencje użytkownika w SharedPreferences aplikacji. Ustaw udostępnione ustawienie w metodzie onPause() aktywności i pobierz je w metodzie onResume(). Więcej informacji o zapisywaniu ustawień znajdziesz w artykule Zapisywanie zbiorów par klucz-wartość.

Dodatkowe materiały

Więcej informacji znajdziesz w tych materiałach:

Przykłady