Geofencing łączy świadomość bieżącej lokalizacji użytkownika ze świadomością odległości od miejsc, które mogą Cię zainteresować. Aby oznaczyć lokalizację interesującej Cię lokalizacji, musisz określić jej szerokość i długość geograficzną. Aby dostosować bliskość dodaj promień. Szerokość, długość i promień wyznaczają geofencing, tworząc okrągłego obszaru lub ogrodzenia wokół wybranej lokalizacji.
Możesz mieć wiele aktywnych geofence z limitem 100 na aplikację na użytkownika urządzenia. Dla każdej wartości geofence, możesz poprosić usługi lokalizacyjne o wysyłanie zdarzeń wejścia i wyjścia, czas oczekiwania w obszarze geofencingu, czyli zamieszanie przed wywołaniem zdarzenia. Ty może ograniczyć czas trwania dowolnego geofence przez określenie czasu ważności w milisekundach. Gdy geofence wygaśnie, usługi lokalizacyjne automatycznie go usuną.
Ta lekcja pokazuje, jak dodawać i usuwać geofencing, a następnie nasłuchiwać przejść geofencingu
za pomocą funkcji BroadcastReceiver
.
Uwaga: na urządzeniach Wear interfejsy Geofencing API nie wykorzystują w efektywny sposób . Nie zalecamy korzystania z tych interfejsów API na Wear. Odczytano Oszczędzaj energię i baterię, aby dowiedzieć się więcej.
Skonfiguruj monitorowanie geofencingu
Aby poprosić o monitorowanie geofencingu, najpierw poproś o niezbędną uprawnień. Aby można było korzystać z geofencingu, aplikacja musi prosić o te uprawnienia:
-
ACCESS_FINE_LOCATION
-
ACCESS_BACKGROUND_LOCATION
jeśli aplikacja jest kierowana na Androida 10 (poziom interfejsu API 29) lub nowszego.
Więcej informacji znajdziesz w przewodniku poprosić o dostęp do lokalizacji.
Jeśli chcesz użyć interfejsu BroadcastReceiver
, aby nasłuchiwać przejść geofencingu,
dodaj element określający nazwę usługi. Ten element musi być
element podrzędny elementu
<application>
:
<application android:allowBackup="true"> ... <receiver android:name=".GeofenceBroadcastReceiver"/> <application/>
Aby uzyskać dostęp do interfejsów API lokalizacji, musisz utworzyć instancję Klient Geofencing. Aby dowiedzieć się, jak połączyć klienta:
Kotlin
lateinit var geofencingClient: GeofencingClient override fun onCreate(savedInstanceState: Bundle?) { // ... geofencingClient = LocationServices.getGeofencingClient(this) }
Java
private GeofencingClient geofencingClient; @Override public void onCreate(Bundle savedInstanceState) { // ... geofencingClient = LocationServices.getGeofencingClient(this); }
Tworzenie i dodawanie geofence
Aplikacja musi utworzyć i dodać geofencje za pomocą klasy kreatora lokalizacji interfejsu API dla
tworzenie obiektów Geofence i klasę wygodną do ich dodawania. Ponadto, aby obsłużyć
intencje wysyłane z usług lokalizacyjnych przy przechodzeniu geofencingu, możesz zdefiniować
PendingIntent
jak pokazano w tej sekcji.
Uwaga: na urządzeniach jednego użytkownika obowiązuje limit 100 geofencingu na aplikację. W przypadku urządzeń, z których korzysta wielu użytkowników, limit wynosi 100 geofencji na aplikację na użytkownika.
Tworzenie obiektów geofence
Najpierw za pomocą funkcji
Geofence.Builder
utwórz geofence, ustawiając odpowiedni promień, czas trwania i
typów przejść dla geofencingu. Aby na przykład wypełnić obiekt listy:
Kotlin
geofenceList.add(Geofence.Builder() // Set the request ID of the geofence. This is a string to identify this // geofence. .setRequestId(entry.key) // Set the circular region of this geofence. .setCircularRegion( entry.value.latitude, entry.value.longitude, Constants.GEOFENCE_RADIUS_IN_METERS ) // Set the expiration duration of the geofence. This geofence gets automatically // removed after this period of time. .setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS) // Set the transition types of interest. Alerts are only generated for these // transition. We track entry and exit transitions in this sample. .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER or Geofence.GEOFENCE_TRANSITION_EXIT) // Create the geofence. .build())
Java
geofenceList.add(new Geofence.Builder() // Set the request ID of the geofence. This is a string to identify this // geofence. .setRequestId(entry.getKey()) .setCircularRegion( entry.getValue().latitude, entry.getValue().longitude, Constants.GEOFENCE_RADIUS_IN_METERS ) .setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS) .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT) .build());
Ten przykład pobiera dane z pliku stałych. W praktyce aplikacje mogą dynamicznie tworzyć granice geograficzne na podstawie lokalizacji użytkownika.
Określanie obszarów geograficznych i aktywatorów początkowych
Ten fragment kodu używa klasy
GeofencingRequest
i zagnieżdżonej klasy
GeofencingRequestBuilder
w
Możesz określić obszary geograficzne, które mają być monitorowane, i określić sposób wywoływania powiązanych zdarzeń geofencingu:
Kotlin
private fun getGeofencingRequest(): GeofencingRequest { return GeofencingRequest.Builder().apply { setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER) addGeofences(geofenceList) }.build() }
Java
private GeofencingRequest getGeofencingRequest() { GeofencingRequest.Builder builder = new GeofencingRequest.Builder(); builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER); builder.addGeofences(geofenceList); return builder.build(); }
Ten przykład pokazuje użycie 2 aktywatorów geofencingu.
GEOFENCE_TRANSITION_ENTER
przejście jest uruchamiane, gdy urządzenie znajdzie się w regionie geofencingu, a
GEOFENCE_TRANSITION_EXIT
przejście jest uruchamiane, gdy urządzenie opuści geofence. Określanie
INITIAL_TRIGGER_ENTER
informuje usługi lokalizacyjne, że
GEOFENCE_TRANSITION_ENTER
powinien zostać wyzwolony, jeśli urządzenie znajduje się już w obrębie geofencingu.
W wielu przypadkach lepiej jest użyć zamiast niego
INITIAL_TRIGGER_DWELL
,
który wywołuje zdarzenia tylko wtedy, gdy użytkownik zatrzyma się na określony czas w obrębie geofencingu.
Takie podejście może pomóc ograniczyć ilość spamu w alertach wynikające z powiadomień o dużej liczbie znaków, gdy
urządzenie na chwilę włącza się i wyłącza funkcje geofence. Inną strategią uzyskiwania
najlepszych wyników
geofence to ustawienie minimalnego promienia 100 metrów. Pomaga to
uwzględnić dokładność lokalizacji
typowe sieci Wi-Fi, a także pomaga zmniejszyć zużycie energii przez urządzenie.
Zdefiniuj odbiornik na potrzeby przejść geofence
Intent
wysłany z usług lokalizacyjnych może wywołać różne działania w
aplikacji, ale nie należy uruchamiać jej aktywności ani fragmentów, ponieważ komponenty
powinny być widoczne tylko w odpowiedzi na działanie użytkownika. W wielu przypadkach BroadcastReceiver
to dobry sposób na obsługę przejść geofencingu. O
BroadcastReceiver
otrzymuje aktualizacje, gdy wystąpi zdarzenie, takie jak
przejść do geofencingu lub z niego i może uruchomić długotrwałe działanie w tle;
w naszej pracy.
Ten fragment kodu pokazuje,
aby zdefiniować PendingIntent
, który zaczyna się BroadcastReceiver
:
Kotlin
class MainActivity : AppCompatActivity() { // ... private val geofencePendingIntent: PendingIntent by lazy { val intent = Intent(this, GeofenceBroadcastReceiver::class.java) // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling // addGeofences() and removeGeofences(). PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) } }
Java
public class MainActivity extends AppCompatActivity { // ... private PendingIntent getGeofencePendingIntent() { // Reuse the PendingIntent if we already have it. if (geofencePendingIntent != null) { return geofencePendingIntent; } Intent intent = new Intent(this, GeofenceBroadcastReceiver.class); // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when // calling addGeofences() and removeGeofences(). geofencePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent. FLAG_UPDATE_CURRENT); return geofencePendingIntent; }
Dodaj granice geograficzne
Aby dodać geofencje, użyj metody
.
Podaj obiekt GeofencingClient.addGeofences()
GeofencingRequest
i PendingIntent
.
Ten fragment kodu ilustruje przetwarzanie wyników:
Kotlin
geofencingClient?.addGeofences(getGeofencingRequest(), geofencePendingIntent)?.run { addOnSuccessListener { // Geofences added // ... } addOnFailureListener { // Failed to add geofences // ... } }
Java
geofencingClient.addGeofences(getGeofencingRequest(), getGeofencePendingIntent()) .addOnSuccessListener(this, new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { // Geofences added // ... } }) .addOnFailureListener(this, new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Failed to add geofences // ... } });
Obsługa przejść geofencingu
Gdy Usługi lokalizacyjne wykryją, że użytkownik włączył geofence lub go opuściła,
wysyła pole Intent
zawarte w PendingIntent
które masz uwzględnione w prośbie o dodanie geofencingu. Odbiornik – np.
Aplikacja GeofenceBroadcastReceiver
zauważa, że został wywołany Intent
,
mogą następnie uzyskać z intencji zdarzenie geofencingu, określić typ przejść geofencingu,
i określić, który ze zdefiniowanych obszarów geograficznych został aktywowany. Transmisja
odbiorca może przekierować aplikację tak, aby rozpoczęła pracę w tle lub
wyślij powiadomienie jako dane wyjściowe.
Uwaga: w Androidzie 8.0 (poziom interfejsu API 26) i nowszych, jeśli aplikacja która działa w tle podczas monitorowania geofencingu, odpowiada na zdarzenia geofencingu co kilka minut. Aby dowiedzieć się, jak się dostosować do tych limitów odpowiedzi, zobacz Informacje ogólne Limity lokalizacji.
Poniższy fragment kodu pokazuje, jak zdefiniować
BroadcastReceiver
który publikuje powiadomienie o przejściu geofencingu. Gdy użytkownik
kliknie powiadomienie, pojawi się główna aktywność w aplikacji:
Kotlin
class GeofenceBroadcastReceiver : BroadcastReceiver() { // ... override fun onReceive(context: Context?, intent: Intent?) { val geofencingEvent = GeofencingEvent.fromIntent(intent) if (geofencingEvent.hasError()) { val errorMessage = GeofenceStatusCodes .getStatusCodeString(geofencingEvent.errorCode) Log.e(TAG, errorMessage) return } // Get the transition type. val geofenceTransition = geofencingEvent.geofenceTransition // Test that the reported transition was of interest. if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER | geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) { // Get the geofences that were triggered. A single event can trigger // multiple geofences. val triggeringGeofences = geofencingEvent.triggeringGeofences // Get the transition details as a String. val geofenceTransitionDetails = getGeofenceTransitionDetails( this, geofenceTransition, triggeringGeofences ) // Send notification and log the transition details. sendNotification(geofenceTransitionDetails) Log.i(TAG, geofenceTransitionDetails) } else { // Log the error. Log.e(TAG, getString(R.string.geofence_transition_invalid_type, geofenceTransition)) } } }
Java
public class GeofenceBroadcastReceiver extends BroadcastReceiver { // ... protected void onReceive(Context context, Intent intent) { GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent); if (geofencingEvent.hasError()) { String errorMessage = GeofenceStatusCodes .getStatusCodeString(geofencingEvent.getErrorCode()); Log.e(TAG, errorMessage); return; } // Get the transition type. int geofenceTransition = geofencingEvent.getGeofenceTransition(); // Test that the reported transition was of interest. if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) { // Get the geofences that were triggered. A single event can trigger // multiple geofences. List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences(); // Get the transition details as a String. String geofenceTransitionDetails = getGeofenceTransitionDetails( this, geofenceTransition, triggeringGeofences ); // Send notification and log the transition details. sendNotification(geofenceTransitionDetails); Log.i(TAG, geofenceTransitionDetails); } else { // Log the error. Log.e(TAG, getString(R.string.geofence_transition_invalid_type, geofenceTransition)); } } }
Po wykryciu zdarzenia przejścia za pomocą interfejsu PendingIntent
BroadcastReceiver
otrzymuje typ przejścia geofencingu,
sprawdza, czy jest to jedno ze zdarzeń używanych przez aplikację do wywoływania
powiadomień – albo
GEOFENCE_TRANSITION_ENTER
lub GEOFENCE_TRANSITION_EXIT
w tej sprawie. Usługa następnie wysyła powiadomienie i zapisuje szczegóły przejścia.
Zatrzymaj monitorowanie geofencingu
Wyłączenie monitorowania geofencingu, gdy nie jest już potrzebne lub potrzebne, może pomóc oszczędzać baterię
i cykli pracy procesora. Możesz zatrzymać monitorowanie geofencingu
w głównej aktywności używanej do dodawania i usuwania geofencingu; usunięcie geofencingu zatrzymuje
natychmiast. Interfejs API udostępnia metody
usunąć granice geograficzne według identyfikatorów żądań lub poprzez usunięcie obszarów geograficznych związanych z danym zapytaniem,
PendingIntent
Ten fragment kodu usuwa geofence przez PendingIntent
, wstrzymując wszystkie
dalsze powiadomienia, gdy urządzenie wejdzie w życie lub je opuści:
Kotlin
geofencingClient?.removeGeofences(geofencePendingIntent)?.run { addOnSuccessListener { // Geofences removed // ... } addOnFailureListener { // Failed to remove geofences // ... } }
Java
geofencingClient.removeGeofences(getGeofencePendingIntent()) .addOnSuccessListener(this, new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { // Geofences removed // ... } }) .addOnFailureListener(this, new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Failed to remove geofences // ... } });
Geofencing możesz połączyć z innymi funkcjami wykorzystującymi lokalizację, na przykład okresowymi aktualizacjami lokalizacji. Więcej informacji znajdziesz w innych lekcjach tych zajęć.
Korzystanie ze sprawdzonych metod dotyczących geofencingu
W tej sekcji znajdziesz zalecenia dotyczące używania geofencingu w lokalizacji. Interfejsy API na Androida.
Zmniejsz zużycie energii
Aby zoptymalizować zużycie energii w aplikacjach korzystających z geofencingu, możesz skorzystać z tych metod:
Ustaw reagowania na powiadomienia na wyższą wartość. Pozwala to zmniejszyć zużycie energii, ponieważ zwiększając czas oczekiwania na alerty geofencingu. Jeśli np. ustawisz wartość responsywności na pięć a aplikacja sprawdza alert wejścia i wyjścia co 5 minut. Ustawienie niższych wartości nie musi oznaczać, że użytkownicy będą powiadamiani w danym okresie (Na przykład jeśli ustawisz wartość 5 sekund, otrzymanie kodu może potrwać trochę dłużej alert).
ustawić większy promień geofencingu w lokalizacjach, w których użytkownik spędza dużo czasu; takich jak dom lub praca. Większe promienie nie zmniejszają bezpośrednio zużycia energii, ale zmniejszają częstotliwość, z jaką aplikacja sprawdza wejście lub wyjście z aplikacji, co skutecznie obniża ogólną moc baterii konsumpcją treści.
Wybierz optymalny promień dla geofencingu
Aby uzyskać najlepsze wyniki, minimalny promień geofencingu powinien wynosić od 100 do 150 metrów. Gdy dostępna jest sieć Wi-Fi, dokładność lokalizacji wynosi zwykle 20–50 metrów. W pomieszczeniu lokalizacja jest dostępna, dokładność może wynosić maksymalnie 5 metrów. Chyba że wiesz, że wewnątrz budynku lokalizacja jest dostępna w obrębie geofencingu, załóżmy, że dokładność lokalizacji Wi-Fi jest 50 metrów.
Jeśli sieć Wi-Fi jest niedostępna (np. jedziesz samochodem na obszarze wiejskim), dokładność lokalizacji jest mniejsza. Zakres dokładności może wynosić od kilkuset metrów kilka kilometrów. W takich przypadkach należy utworzyć granice geograficzne, korzystając z większego promienia.
Wyjaśnij użytkownikom, dlaczego Twoja aplikacja używa geofencingu
Podczas korzystania z geofencingu aplikacja uzyskuje dostęp do lokalizacji w tle, zastanów się, jak Twoja aplikacja przynosi korzyści użytkownikom. Wyjaśnij dziecku, dlaczego. aplikacja potrzebuje tego dostępu, aby zwiększyć przejrzystość i zrozumienie użytkowników.
Aby dowiedzieć się więcej o sprawdzonych metodach dostępu do lokalizacji, w tym geofencing, zobacz najlepszą ochronę prywatności metod weryfikacji danych.
Używanie typu przejścia bez kontaktu w celu ograniczenia spamu w alertach
Jeśli podczas krótkiej przejeżdżania obok geofencingu otrzymujesz dużą liczbę alertów,
zmniejsz liczbę alertów, użyj typu przejścia
GEOFENCE_TRANSITION_DWELL
zamiast
GEOFENCE_TRANSITION_ENTER
. Dzięki temu alert dotyczący miejsca zamieszkania jest wysyłany tylko wtedy, gdy użytkownik przestaje działać.
w obrębie geofencingu w danym okresie. Aby wybrać czas trwania, ustaw
opóźnienia w ruchu.
Ponowna rejestracja geofencingu tylko wtedy, gdy jest to wymagane
Zarejestrowane granice geograficzne są przechowywane w procesie com.google.process.location
, którego właścicielem jest
pakiet com.google.android.gms
.
Aplikacja nie musi nic robić do obsługi tych zdarzeń, bo system
przywraca geofencje po tych zdarzeniach:
- Usługi Google Play zostały uaktualnione.
- Usługi Google Play są wyłączane i uruchamiane ponownie przez system z powodu ograniczenia zasobów.
- Proces lokalizacji ulega awarii.
Aplikacja musi ponownie zarejestrować geofencing, jeśli są nadal potrzebne po tych wydarzeniach, ponieważ system nie może przywrócić geoferencji w tych przypadkach:
- Urządzenie zostało zrestartowane. Aplikacja powinna nasłuchiwać zakończenia uruchamiania urządzenia, a następnie – zarejestrować wymagane geofence.
- Aplikacja zostanie odinstalowana i zainstalowana ponownie.
- Dane aplikacji zostaną wyczyszczone.
- Dane Usług Google Play zostały wyczyszczone.
- Aplikacja otrzymała
GEOFENCE_NOT_AVAILABLE
alert. Zwykle dzieje się tak po wyłączeniu NLP (dostawcy lokalizacji sieciowej na Androida).
Rozwiązywanie problemów ze zdarzeniem wejścia do geofencingu
Jeśli geofencing nie jest wyzwalany, gdy urządzenie wchodzi w interakcję z funkcją geofencingu
(alert
GEOFENCE_TRANSITION_ENTER
nie jest wyzwalany), najpierw upewnij się, że granice geograficzne są
prawidłowo zarejestrowane, tak jak to opisano w tym przewodniku.
Oto kilka możliwych powodów, dla których alerty nie działają zgodnie z oczekiwaniami:
- W obrębie Twojego geofencingu nie jest dostępna dokładna lokalizacja lub geofence też jest niedostępne Na większości urządzeń usługa geofence używa tylko lokalizacji sieciowej na potrzeby geofencingu które wywołujące stres. Usługa stosuje tę metodę, ponieważ lokalizacja sieciowa zużywa znacznie mniej energia elektryczna, dojazd do wybranych lokalizacji zajmuje mniej czasu, a co najważniejsze, jest dostępne wewnątrz budynków.
Wi-Fi na urządzeniu jest wyłączone. Włączenie Wi-Fi może znacznie poprawić jakość połączenia dokładności lokalizacji, więc jeśli Wi-Fi jest wyłączone, aplikacja może nie otrzymywać alertów geofence. w zależności od różnych ustawień, w tym promienia geofencingu, modelu urządzenia lub Wersja Androida. Począwszy od Androida 4.3 (poziom API 18) dodaliśmy możliwość skanowania Wi-Fi „tylko tryb”, który pozwala użytkownikom wyłączyć Wi-Fi, ale nadal korzystać z dobrej lokalizacji sieciowej. To dobrze ćwiczenie promptów i udostępniania mu skrótu umożliwiającego włączenie tylko skanowania Wi-Fi lub Wi-Fi , jeśli oba tryby są wyłączone. Użyj formatu SettingsClient, aby zapewnić odpowiednią konfigurację ustawień systemowych urządzenia. wykrywanie lokalizacji.
Uwaga: jeśli aplikacja jest kierowana na Androida 10 (poziom interfejsu API 29) lub wyżej, nie można zadzwonić bezpośrednio pod numer
WifiManager.setEnabled()
, Twoja aplikacja jest aplikacją systemową lub zasadami dotyczącymi urządzeń (DPC). Zamiast tego użyj panelu ustawień.- W obrębie geofencingu nie ma niezawodnego połączenia sieciowego. Jeśli Brak niezawodnego połączenia do transmisji danych, mogą nie być generowane alerty. Dzieje się tak, ponieważ usługa geofence zależy od operatora lokalizacji, co z kolei wymaga połączenia transmisji danych.
- Alerty mogą być opóźnione. Usługa geofencingu nie wysyła stale zapytań lokalizacji, więc alerty mogą pojawić się z opóźnieniem. Zazwyczaj opóźnienie jest mniejsze niż 2. nawet mniej, gdy urządzenie jest w ruchu. Jeśli Informacje ogólne Obowiązują limity lokalizacji. Opóźnienie wynosi średnio 2–3 minuty. Jeśli urządzenie było nieruchome przez dłuższy czas, opóźnienie może wzrosnąć (do 6 minut).
Dodatkowe materiały
Więcej informacji o geofencingu znajdziesz w tych materiałach:
Próbki
Przykładowa aplikacja do tworzenia i monitorowania obszarów geograficznych.