Poproś o aktualizacje lokalizacji

Odpowiednie korzystanie z informacji o lokalizacji może być korzystne dla użytkowników aplikacji. Na przykład jeśli aplikacja pomaga użytkownikowi znaleźć drogę podczas spaceru lub jazdy samochodem lub jeśli aplikacja śledzi lokalizację zasobów, musi regularnie uzyskiwać lokalizację urządzenia. Oprócz lokalizacji geograficznej (szerokości i długości geograficznej) możesz też podać użytkownikowi dodatkowe informacje, takie jak kierunek podróży (kierunek w poziomie), 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 aktualnych dostawców lokalizacji, takich jak Wi-Fi czy GPS (globalny system pozycjonowania). Dokładność lokalizacji zależy od dostawców, oczekiwanych uprawnień dostępu do lokalizacji i opcji ustawionych w prośbie o lokalizację.

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

Uzyskiwanie ostatniej znanej lokalizacji

Ostatnia znana lokalizacja urządzenia jest przydatną podstawą, od której można zacząć. Przed rozpoczęciem okresowych aktualizacji lokalizacji aplikacja powinna mieć znaną lokalizację. Z lekcji na temat uzyskiwania ostatniej znanej lokalizacji dowiesz się, jak uzyskać ostatnią znaną lokalizację, dzwoniąc do getLastLocation(). Fragmenty kodu w poniższych sekcjach zakładają, że aplikacja pobrała już ostatnią znaną lokalizację i zapisała ją jako obiekt Location w zmiennej globalnej mCurrentLocation.

Prześlij prośbę o lokalizację

Zanim poprosisz o aktualizację lokalizacji, aplikacja musi połączyć się z usługami lokalizacyjnymi i wysłać prośbę o lokalizację. Z lekcji na temat zmieniania ustawień lokalizacji dowiesz się, jak to zrobić. Po przesłaniu prośby o lokalizację możesz rozpocząć regularne aktualizacje, dzwoniąc pod numer requestLocationUpdates().

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

Z tej lekcji dowiesz się, jak uzyskać aktualizację za pomocą wywołania zwrotnego LocationCallback. Wywołaj requestLocationUpdates(), przekazując do niej 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());
}

Zwróć uwagę, że powyższy fragment kodu odnosi się do flagi wartości logicznej requestingLocationUpdates, która służy do śledzenia, czy użytkownik włączył lub wyłączył aktualizowanie lokalizacji. Jeśli użytkownicy wyłączyli aktualizowanie lokalizacji, możesz poinformować ich o wymaganiach dotyczących lokalizacji w aplikacji. Więcej informacji o zachowywaniu wartości flagi wartości logicznej w 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 obiekt listy Location zawierający szerokość i długość geograficzną lokalizacji. Ten fragment kodu pokazuje, jak wdrożyć interfejs LocationCallback i zdefiniować metodę, a potem uzyskać sygnaturę czasową aktualizacji lokalizacji oraz wyświetlić szerokość, długość geograficzną i 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
                // ...
            }
        }
    };
}

Zatrzymaj aktualizacje lokalizacji

Zastanów się, czy chcesz zatrzymać aktualizowanie lokalizacji, gdy aktywność nie jest już widoczna, np. gdy użytkownik przełącza się na inną aplikację lub robi to w tej samej aplikacji. Może to być przydatne, ponieważ pozwala zmniejszyć zużycie energii, o ile aplikacja nie musi zbierać informacji nawet wtedy, gdy działa w tle. W tej sekcji pokazujemy, jak możesz zatrzymać aktualizacje w metodzie onPause() aktywności.

Aby zatrzymać aktualizowanie lokalizacji, wywołaj removeLocationUpdates() i przekaż mu 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 aktualizowanie lokalizacji jest obecnie włączone. W metodzie onResume() aktywności sprawdź, czy aktualizacje lokalizacji są obecnie aktywne. 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, na przykład zmiana orientacji lub języka ekranu, może spowodować zniszczenie bieżącej aktywności. Dlatego aplikacja musi przechowywać wszystkie informacje potrzebne do odtworzenia aktywności. Możesz to zrobić na przykład za pomocą stanu instancji zapisanego 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 poprzedniego wystąpienia 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 Aktywność na Androidzie.

Uwaga: aby zwiększyć pamięć trwałą, możesz zapisać ustawienia użytkownika w pliku SharedPreferences aplikacji. Ustaw wspólne preferencje w metodzie onPause() aktywności i pobierz je w funkcji onResume(). Więcej informacji o zapisywaniu ustawień znajdziesz w sekcji Zapisywanie zestawów par klucz-wartość.

Dodatkowe materiały

Aby dowiedzieć się więcej, skorzystaj z tych materiałów:

Próbki