Poproś o aktualizacje lokalizacji

Właściwe korzystanie z informacji o lokalizacji może być korzystne dla użytkowników aplikacji. Jeśli na przykład aplikacja pomaga użytkownikowi znaleźć drogę, gdy idzie pieszo lub samochodem albo jeśli śledzi lokalizację zasobów, musi regularnie uzyskiwać informacje o lokalizacji urządzenia. Oprócz lokalizacji geograficznej (długości i szerokości geograficznej) możesz podać użytkownikowi dodatkowe informacje, takie jak przesunięcie (kierunek poziomy), 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 Twoją aplikację przy użyciu najlepszej dostępnej lokalizacji w oparciu o aktualnie dostępnych dostawców lokalizacji, takich jak WiFi czy GPS (Global Positioning System). Dokładność lokalizacji zależy od dostawców, prośby o przyznanie uprawnień do lokalizacji i opcji ustawionych w prośbie o lokalizację.

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

Pobierz ostatnią znaną lokalizację

Ostatnia znana lokalizacja urządzenia to dobra baza, od której można zacząć. Aplikacja ma znaną lokalizację, zanim rozpocznie okresowe aktualizacje lokalizacji. Z lekcji na temat określania ostatniej znanej lokalizacji dowiesz się, jak uzyskać ostatnią znaną lokalizację, dzwoniąc do telefonu getLastLocation(). Fragmenty kodu w poniższych sekcjach zakładają, że Twoja 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 przesłać prośbę o dostęp do lokalizacji. Jak to zrobić, dowiesz się z lekcji Zmienianie ustawień lokalizacji. Po wysłaniu prośby o lokalizację możesz rozpocząć regularne aktualizacje, 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 listę obiektów Location lub wysyła obiekt PendingIntent, który zawiera lokalizację w rozszerzonych danych. Dokładność i częstotliwość aktualizacji zależą od żądanych uprawnień dostępu do lokalizacji oraz opcji ustawionych w obiekcie prośby o lokalizację.

Z tej lekcji dowiesz się, jak pobrać aktualizację z użyciem metody wywołania zwrotnego LocationCallback. Wywołaj requestLocationUpdates(), przekazując do niej instancję obiektu LocationRequest oraz LocationCallback. Zdefiniuj metodę startLocationUpdates() zgodnie z tym przykładowym kodem:

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, używanej do śledzenia, czy użytkownik włączył czy wyłączenie aktualizacji lokalizacji. Jeśli użytkownik wyłączył aktualizacje lokalizacji, możesz poinformować ich o wymaganiach aplikacji dotyczących lokalizacji. Więcej informacji o zachowywaniu wartości flagi wartości logicznej w instancjach działania 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(). Przychodzący argument 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 pobrać sygnaturę czasową aktualizacji lokalizacji i wyświetlić szerokość, 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
                // ...
            }
        }
    };
}

Wyłączanie aktualizacji lokalizacji

Zastanów się, czy chcesz zatrzymać aktualizacje lokalizacji, gdy aktywność przestaje być widoczna, na przykład gdy użytkownik przełącza się na inną aplikację lub wykonuje inne działanie w tej samej aplikacji. Pomaga to zmniejszyć zużycie 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ć aktualizacje lokalizacji, wywołaj removeLocationUpdates(), przekazując mu 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);
}

Aby śledzić, czy aktualizacje lokalizacji są obecnie włączone, użyj wartości logicznej requestingLocationUpdates. W metodzie onResume() aktywności sprawdź, czy aktualizacje 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();
    }
}

Zapisz stan aktywności

Zmiana konfiguracji urządzenia, na przykład zmiana orientacji ekranu lub języka, może spowodować zniszczenie bieżącej aktywności. Aplikacja musi więc 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 do zapisania stanu 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 klas Aktywność na Androidzie.

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

Dodatkowe materiały

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

Próbki