Optymalizuj lokalizację, aby oszczędzać baterię

Limity lokalizacji w tle wprowadzone w Androidzie 8.0 (poziom interfejsu API 26) ponownie skupiły się na tym, jak korzystanie z usług lokalizacyjnych wpływa na zużycie baterii. Na tej stronie opisujemy kilka sprawdzonych metod dotyczących usług lokalizacyjnych i przedstawiamy, co możesz teraz zrobić, aby Twoje aplikacje oszczędzały baterię. Zastosowanie tych sprawdzonych metod przyniesie korzyści Twojej aplikacji niezależnie od wersji platformy, na której działa.

Limity lokalizacji w tle w Androidzie 8.0 wprowadziły te zmiany:

  • Zbieranie danych o lokalizacji w tle jest ograniczone, a dane o lokalizacji są obliczane i dostarczane tylko kilka razy na godzinę.
  • Skanowanie Wi-Fi jest bardziej zachowawcze, a aktualizacje lokalizacji nie są obliczane, gdy urządzenie pozostaje połączone z tym samym statycznym punktem dostępu.
  • Czas reakcji geofencingu zmienia się z dziesiątek sekund na około dwie minuty. Ta zmiana znacznie poprawia wydajność baterii – na niektórych urządzeniach nawet 10 razy lepiej.

Na tej stronie zakładamy, że używasz interfejsów API usług lokalizacyjnych Google, które zapewniają większą dokładność i zmniejszają obciążenie baterii niż interfejsy API lokalizacji platformy. Szczególnie ta strona zakłada znajomość interfejsu API dostawcy uśrednionej lokalizacji, który łączy sygnały z GPS-u, Wi-Fi i sieci komórkowych, a także akcelerometr, żyroskop, magnetometr i inne czujniki. Zapoznaj się też z interfejsem API geoofencingu, który jest oparty na interfejsie API dostawcy uśrednionej lokalizacji i jest zoptymalizowany pod kątem wydajności baterii.

Informacje o szybkim zużyciu baterii

Zbieranie danych o lokalizacji i zużycie baterii są bezpośrednio powiązane z tymi aspektami:

  • Dokładność: dokładność danych o lokalizacji. Ogólnie im wyższa dokładność, tym większe zużycie baterii.
  • Częstotliwość: jak często lokalizacja jest wyznaczana. Im częściej ustalasz lokalizację, tym większe jest zużycie baterii.
  • Opóźnienie – jak szybko dane o lokalizacji są dostarczane. Krótszy czas oczekiwania zwykle wymaga więcej baterii.

Dokładność

Dokładność lokalizacji możesz określić za pomocą metody setPriority(), przekazując jako argument jedną z tych wartości:

  • PRIORITY_HIGH_ACCURACY podaje możliwie najdokładniejszą lokalizację, która jest obliczana na podstawie jak największej liczby niezbędnych danych wejściowych (włącza GPS, Wi-Fi i sieć komórkową oraz używa różnych czujników) i może spowodować znaczne zużycie baterii.
  • Urządzenie PRIORITY_BALANCED_POWER_ACCURACY podaje dokładną lokalizację przy jednoczesnej optymalizacji zużycia energii. Bardzo rzadko korzysta z GPS. Zwykle do określania lokalizacji urządzenia używana jest kombinacja informacji o sieci Wi-Fi i sieci komórkowej.
  • PRIORITY_LOW_POWER Działanie w dużej mierze bazuje na stacjach bazowych sieci komórkowych i nie wymaga wejść GPS ani Wi-Fi, co zapewnia przybliżoną dokładność (na poziomie miasta) przy minimalnym zużyciu baterii.
  • PRIORITY_NO_POWER otrzymuje lokalizacje pasywnie z innych aplikacji, w przypadku których lokalizacja została już obliczona.

W przypadku większości aplikacji funkcje lokalizacji można zaspokoić, korzystając z opcji zrównoważonego zasilania lub oszczędzania energii. Wysoka dokładność powinna być zarezerwowana dla aplikacji działających na pierwszym planie i wymagających aktualizacji lokalizacji w czasie rzeczywistym (np. aplikacji z mapami).

Częstotliwość

Częstotliwość lokalizacji możesz określić na 2 sposoby:

  • Aby określić odstęp czasu, w którym obliczana jest lokalizacja Twojej aplikacji, użyj metody setinterval().
  • setFastestInterval() pozwala określić odstęp czasu, po którym lokalizacja obliczona dla innych aplikacji jest dostarczana do Twojej aplikacji.

Gdy używasz funkcji setInterval(), musisz przekazać największą możliwą wartość. Zwłaszcza w przypadku gromadzenia danych o lokalizacji w tle, które często prowadzi do niechcianego rozładowywania baterii. Stosowanie kilkusekundowych odstępów powinno być zarezerwowane tylko do stosowania na pierwszym planie. Limity lokalizacji w tle wprowadzone w Androidzie 8.0 egzekwują te strategie, ale Twoja aplikacja powinna być egzekwowana na urządzeniach z Androidem 7.0 lub starszym.

Opóźnienie

Czas oczekiwania możesz określić za pomocą metody setMaxWaitTime(), zwykle przesyłając wartość kilka razy większą niż przedział określony w metodzie setInterval(). To ustawienie opóźnia dostarczenie lokalizacji, a wiele aktualizacji lokalizacji może być dostarczanych partiami. Te dwie zmiany pomagają zminimalizować zużycie baterii.

Jeśli aplikacja nie wymaga od razu aktualizacji lokalizacji, przekaż największą możliwą wartość do metody setMaxWaitTime(), efektywnie zamieniając opóźnienie w celu uzyskania większej ilości danych i oszczędności baterii.

Gdy używasz geofence, aplikacje powinny przekazywać dużą wartość do metody setNotificationResponsiveness(), aby oszczędzać energię. Zalecana jest wartość co najmniej 5 minut.

Przypadki użycia lokalizacji

W tej sekcji opisujemy kilka typowych scenariuszy zbierania danych o lokalizacji oraz przedstawiamy zalecenia dotyczące optymalnego korzystania z geofencingu i interfejsów API dostawcy scalonej lokalizacji.

Aktualizacje widoczne lub na pierwszym planie przez użytkownika

Przykład: aplikacja do map, która wymaga częstych, dokładnych aktualizacji z bardzo niewielkim opóźnieniem. Wszystkie aktualizacje odbywają się na pierwszym planie: użytkownik rozpoczyna działanie, pobiera dane o lokalizacji, a potem po krótkim czasie zatrzymuje działanie.

Użyj metody setPriority() z wartością PRIORITY_HIGH_ACCURACY lub PRIORITY_BALANCED_POWER_ACCURACY.

Interwał określony w metodzie setInterval() zależy od konkretnego przypadku użycia: w przypadku scenariuszy w czasie rzeczywistym ustaw wartość na kilka sekund. W przeciwnym razie czas nieprzekraczający kilku minut (zalecamy odstąpienie od około 2 minut, aby zminimalizować wykorzystanie baterii).

Rozpoznawanie lokalizacji urządzenia

Przykład: aplikacja pogodowa chce poznać lokalizację urządzenia.

Użyj metody getLastLocation(), która zwraca najnowszą dostępną lokalizację (która w rzadkich przypadkach może mieć wartość null) . Ta metoda zapewnia prosty sposób uzyskiwania informacji o lokalizacji i nie wiąże się z kosztami związanymi z aktywnym przesyłaniem próśb o aktualizację lokalizacji. Używaj w połączeniu z metodą isLocationAvailable(), która zwraca wartość true, jeśli lokalizacja zwrócona przez metodę getLastLocation() jest wystarczająco aktualna.

Uruchamianie aktualizacji, gdy użytkownik znajduje się w określonej lokalizacji

Przykład: wysyłanie prośby o aktualizację, gdy użytkownik znajduje się w określonej odległości od pracy, domu lub innego miejsca.

Używaj geofencingu w połączeniu z aktualizacjami dostawców uśrednionej lokalizacji. Wysyłanie żądań aktualizacji, gdy aplikacja otrzyma regułę wejścia geofencingu, i usunięcie aktualizacji po otrzymaniu aktywatora wyjścia geofence. Dzięki temu aplikacja otrzymuje bardziej szczegółowe aktualizacje lokalizacji tylko wtedy, gdy użytkownik wejdzie na wyznaczony obszar.

Typowym przepływem pracy w tym scenariuszu może być wyświetlenie powiadomienia przy przejściu geofencingu i uruchomienie działania zawierającego kod żądania aktualizacji po kliknięciu powiadomienia przez użytkownika.

Uruchamianie aktualizacji na podstawie stanu aktywności użytkownika

Przykład: żądanie aktualizacji tylko wtedy, gdy użytkownik jedzie na rowerze lub jeździ na rowerze.

Interfejs Activity Recognition API musi być połączony z aktualizacjami dostawcy uśrednionej lokalizacji. Wysyłanie żądań aktualizacji, gdy wykryta aktywność zostanie wykryta, i usunięcie aktualizacji, gdy użytkownik przestanie wykonywać daną aktywność.

Typowym przepływem pracy w tym przypadku użycia jest wyświetlenie powiadomienia o wykrytej aktywności i uruchomienie działania, które zawiera kod żądania aktualizacji po kliknięciu powiadomienia przez użytkownika.

Długo trwające aktualizacje lokalizacji w tle powiązane z obszarami geograficznymi

Przykład: użytkownik chce otrzymać powiadomienie, gdy urządzenie znajdzie się w pobliżu sprzedawcy.

To doskonały przypadek użycia geofencingu. Przypadek użycia niemal na pewno dotyczy lokalizacji w tle, więc użyj metody addGeofences(GeofencingRequest, PendingIntent).

Ustaw następujące opcje konfiguracji:

  • Jeśli śledzisz przejścia zatrzymujące się, użyj metody setLoiteringDelay(), podając wartość około 5 minut lub mniejszą.

  • Użyj kodu setNotificationResponsiveness() z wartością około 5 minut. Jeśli aplikacja jest w stanie poradzić sobie z dodatkowym opóźnieniem reagowania, zastanów się nad użyciem wartości około 10 minut.

Aplikacja może zarejestrować maksymalnie 100 geofencingu. W sytuacji, gdy aplikacja chce śledzić dużą liczbę opcji sprzedawcy, może zarejestrować duże geofencing (na poziomie miasta) i dynamicznie rejestrować mniejsze geofencing (dla lokalizacji w mieście) dla sklepów w obrębie większego geofencingu. Gdy użytkownik wejdzie na duży geofencing, można dodać mniejsze.

Długo trwające aktualizacje lokalizacji w tle bez widocznego komponentu aplikacji

Przykład: aplikacja, która pasywnie śledzi lokalizację

W miarę możliwości używaj metody setPriority() z opcją PRIORITY_NO_POWER, ponieważ prawie nie obciąża ona baterii. Jeśli użycie PRIORITY_NO_POWER nie jest możliwe, użyj PRIORITY_BALANCED_POWER_ACCURACY lub PRIORITY_LOW_POWER. Unikaj jednak używania PRIORITY_HIGH_ACCURACY do długotrwałej pracy w tle, ponieważ ta opcja znacznie obciąża baterię.

Jeśli potrzebujesz więcej danych o lokalizacji, użyj lokalizacji pasywnej, wywołując metodę setFastestInterval(), przekazując wartość mniejszą niż ta, którą przekazujesz do setInterval(). W połączeniu z opcją PRIORITY_NO_POWER lokalizacja pasywna może udostępniać bez dodatkowych kosztów lokalizację określoną przez inne aplikacje.

Umiarkowana częstotliwość przez zwiększenie opóźnienia przy użyciu metody setMaxWaitTime(). Jeśli na przykład używasz metody setinterval() z wartością około 10 minut, rozważ wywołanie metody setMaxWaitTime() z wartością z zakresu od 30 do 60 minut. Dzięki tym opcjom lokalizacja jest obliczana dla aplikacji mniej więcej co 10 minut, ale aplikacja budzi się tylko co 30–60 minut, a niektóre dane o lokalizacji są dostępne w ramach aktualizacji zbiorczej. Ta metoda pozwala skrócić czas oczekiwania na większą ilość dostępnych danych i lepszą wydajność baterii.

Częste aktualizacje o wysokiej dokładności, gdy użytkownik korzysta z innych aplikacji.

Przykład: aplikacja do nawigacji lub fitness, która wciąż działa, gdy użytkownik wyłączy ekran lub otworzy inną aplikację.

korzystać z usługi na pierwszym planie, Jeśli aplikacja może wykonywać kosztowne działania w imieniu użytkownika, warto poinformować o tym użytkownika. Usługa na pierwszym planie wymaga trwałego powiadomienia. Więcej informacji znajdziesz w artykule Omówienie powiadomień.

Sprawdzone metody dotyczące lokalizacji

Sprawdzone metody opisane w tej sekcji pomogą Ci ograniczyć wykorzystanie baterii przez aplikację.

Usuń aktualizacje lokalizacji

Częstym źródłem nadmiernego zużycia baterii jest nieusuwanie aktualizacji lokalizacji, gdy nie są już potrzebne. Może się tak zdarzyć, jeśli na przykład metody onStart() lub onResume() cyklu życia aktywności zawierają wywołanie requestlocationUpdates() bez odpowiadającego jej wywołania removeLocationUpdates() w metodach cyklu życia onPause() lub onStop().

Za pomocą komponentów uwzględniających cykl życia możesz lepiej zarządzać cyklem życia działań w aplikacji. Więcej informacji znajdziesz w artykule o obsłudze cyklu życia za pomocą komponentów odzwierciedlających cykl życia.

Ustawianie limitów czasu oczekiwania

Aby zapobiec rozładowywaniu się baterii, ustaw odpowiedni czas oczekiwania, kiedy aktualizacje lokalizacji mają się zatrzymywać. Przekroczenie limitu czasu gwarantuje, że aktualizacje nie będą kontynuowane w nieskończoność oraz chroni aplikację w sytuacjach, gdy prośba o aktualizację zostanie wysłana, ale nie zostanie ona usunięta (np. z powodu błędu w kodzie).

W przypadku żądania dostawcy uśrednionej lokalizacji dodaj limit czasu, wywołując metodę setExpirationDuration(), która otrzymuje parametr reprezentujący czas od ostatniego wywołania metody w milisekundach. Możesz też dodać limit czasu, wywołując metodę setExpirationTime(), która otrzymuje parametr określający czas wygaśnięcia w milisekundach od ostatniego uruchomienia systemu.

Aby dodać czas oczekiwania do żądania lokalizacji geofencingu, wywołaj metodę setExpirationDuration().

Żądania zbiorcze

Na potrzeby wszystkich przypadków użycia spoza pierwszego planu zgrupuj wiele żądań. Aby określić przedział czasu, w którym chcesz obliczyć lokalizację, możesz użyć metody setInterval(). Następnie za pomocą metody setMaxWaitTime() ustaw odstęp czasu, w którym lokalizacja jest dostarczona do aplikacji. Wartość przekazywana do metody setMaxWaitTime() powinna być wielokrotnością wartości przekazanej do metody setInterval(). Weźmy na przykład to żądanie lokalizacji:

Kotlin

val request = LocationRequest()
request.setInterval(10 * 60 * 1000)
request.setMaxWaitTime(60 * 60 * 1000)

Java

LocationRequest request = new LocationRequest();
request.setInterval(10 * 60 * 1000);
request.setMaxWaitTime(60 * 60 * 1000);

W tym przypadku lokalizacja jest obliczana co około 10 minut, a około 6 punktów danych o lokalizacji jest dostarczanych zbiorczo co około godzinę. Chociaż lokalizacja jest aktualizowana co około 10 minut, oszczędzasz baterię, bo urządzenie wybudza się tylko co godzinę.

Korzystanie z pasywnych aktualizacji lokalizacji

W przypadkach użycia w tle warto ograniczyć aktualizacje lokalizacji. Limity w Androidzie 8.0 egzekwują tę praktykę, ale w przypadku aplikacji działających na starszych urządzeniach należy w miarę możliwości ograniczać lokalizację w tle.

Możliwe, że gdy Twoja aplikacja działa w tle, inna aplikacja może często prosić o aktualizację lokalizacji na pierwszym planie. Usługi lokalizacyjne udostępniają te aktualizacje Twojej aplikacji. Weź pod uwagę to żądanie lokalizacji, które okazjonalnie zużywa dane o lokalizacji:

Kotlin

val request = LocationRequest()
request.setInterval(15 * 60 * 1000)
request.setFastestInterval(2 * 60 * 1000)

Java

LocationRequest request = new LocationRequest();
request.setInterval(15 * 60 * 1000);
request.setFastestInterval(2 * 60 * 1000);

W poprzednim przykładzie lokalizacja aplikacji jest obliczana co około 15 minut. Jeśli inne aplikacje żądają lokalizacji, dane są udostępniane aplikacji z maksymalnie 2-minutowym odstępem.

Chociaż pasywne korzystanie z lokalizacji nie powoduje rozładowywania baterii, zachowaj szczególną ostrożność, jeśli otrzymywanie danych o lokalizacji wymaga kosztownych operacji procesora lub wejścia/wyjścia. Aby zminimalizować koszty baterii, interwał określony w polu setFastestInterval() nie powinien być zbyt krótki.

Możesz znacznie poprawić wydajność baterii urządzeń użytkowników, postępując zgodnie z zaleceniami na tej stronie. Jest mniej prawdopodobne, że użytkownicy usuną aplikacje, które nie obciążają baterii.