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ę podczas chodzenia lub jazdy, albo jeśli aplikacja śledzi lokalizację zasobów, musi w regularnych odstępach czasu 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 przemieszczania się), 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 na to interfejs API okresowo aktualizuje aplikację, podając najdokładniejszą dostępną lokalizację na podstawie aktualnie dostępnych dostawców lokalizacji, takich jak Wi-Fi czy GPS (Global Positioning System). Dokładność lokalizacji jest określana przez dostawców, uprawnienia dostępu do lokalizacji oraz opcje ustawione w prośbie o lokalizację.

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

Pobieranie ostatniej znanej lokalizacji

Ostatnia znana lokalizacja urządzenia stanowi wygodną podstawę do rozpoczęcia, dzięki czemu aplikacja ma znaną lokalizację przed rozpoczęciem okresowych aktualizacji lokalizacji. W lekcji Pobieranie ostatniej znanej lokalizacji dowiesz się, jak pobrać ostatnią znaną lokalizację, wywołując getLastLocation(). Fragmenty kodu w następnych sekcjach zakładają, że Twoja 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ć prośbę o lokalizację. Jak to zrobić, dowiesz się z lekcji Zmienianie ustawień lokalizacji. Gdy prośba o lokalizację zostanie przesłana, możesz rozpocząć regularne aktualizacje, dzwoniąc pod numer requestLocationUpdates().

W zależności od formy żądania dostawca złączonej lokalizacji albo wywołuje metodę wywołania zwrotnego LocationCallback.onLocationResult() i przekazuje jej listę obiektów Location, albo wydaje żądanie PendingIntent, które zawiera lokalizację w rozszerzonych danych. Dokładność i częstotliwość aktualizacji zależą od żądanych przez Ciebie uprawnień dostępu do lokalizacji oraz opcji ustawionych w obiekcie żądania lokalizacji.

W tej lekcji dowiesz się, jak uzyskać aktualizację za pomocą metody wywołania zwrotnego LocationCallback. Wywołaj funkcję requestLocationUpdates(), przekazując jej instancję obiektu LocationRequest i element LocationCallback. Zdefiniuj metodę startLocationUpdates(), jak 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 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żytkownik wyłączył aktualizacje lokalizacji, możesz poinformować go o wymaganiach dotyczących lokalizacji w aplikacji. Więcej informacji o zachowywaniu wartości flagi logicznej w przypadkach aktywności znajdziesz w artykule Zapisywanie stanu aktywności.

Definiowanie wywołania zwrotnego po aktualizacji lokalizacji

Dostawca uśrednionej lokalizacji wywołuje metodę wywołania zwrotnego LocationCallback.onLocationResult(). Argument wejściowy zawiera obiekt listy Location zawierający szerokość i długość geograficzną lokalizacji. Poniższy fragment kodu pokazuje, jak zaimplementować interfejs LocationCallback i zdefiniować metodę, a potem pobrać sygnaturę czasową aktualizacji lokalizacji i wyświetlić szerokość geograficzną, 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
                // ...
            }
        }
    };
}

Zatrzymanie aktualizacji lokalizacji

Zastanów się, czy chcesz zatrzymać aktualizacje lokalizacji, gdy dana aktywność przestanie być aktywna, np. gdy użytkownik przełączy się na inną aplikację lub inną aktywność w tej samej aplikacji. Może to być przydatne, aby zmniejszyć zużycie 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 parametr 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 metodie onResume() działania sprawdź, czy aktualizacje lokalizacji są obecnie aktywne, a jeśli nie, to 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 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 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 poprzedniego wystąpienia aktywności, jeśli są dostępne. Wywołaj metodę onCreate() z 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ć trwałe przechowywanie, możesz zapisać ustawienia użytkownika w SharedPreferences aplikacji. Ustaw udostępnione ustawienie w metodzie onPause() aktywności, a potem pobierz to ustawienie w metodzie onResume(). Więcej informacji o zapisywaniu ustawień znajdziesz w artykule Zapisywanie zestawów klucz-wartość.

Dodatkowe materiały

Więcej informacji znajdziesz w tych materiałach:

Próbki