Beim Geofencing wird der aktuelle Standort des Nutzers mit der Nähe des Nutzers zu Orten kombiniert, die für ihn von Interesse sein könnten. Um einen interessanten Ort zu markieren, geben Sie seinen Breiten- und Längengrad an. Um die Nähe für den Standort anzupassen, fügen Sie einen Radius hinzu. Breiten- und Längengrad sowie Radius definieren einen Geofence, der einen kreisförmigen Bereich oder Zaun um den interessierenden Standort bildet.
Sie können mehrere aktive Geofences haben, wobei das Limit bei 100 pro App und Gerätebenutzer liegt. Für jeden Geofence können Sie festlegen, dass Sie Ein- und Ausstiegsereignisse erhalten, oder eine Dauer innerhalb des Geofence-Bereichs angeben, die abgewartet werden soll, bevor ein Ereignis ausgelöst wird. Diese Dauer wird als Verweildauer bezeichnet. Sie können die Dauer eines beliebigen Geofence begrenzen, indem Sie eine Ablaufdauer in Millisekunden angeben. Nach Ablauf des Geofence wird er automatisch von den Standortdiensten entfernt.

In dieser Lektion erfahren Sie, wie Sie Geofences hinzufügen und entfernen und dann mit einem BroadcastReceiver
auf Geofence-Übergänge reagieren.
Hinweis:Auf Wear-Geräten wird durch die Geofencing APIs nicht effizient Strom verbraucht. Wir empfehlen diese APIs nicht für Wear. Weitere Informationen finden Sie unter Energie und Akku schonen.
Geofence-Monitoring einrichten
Der erste Schritt beim Anfordern der Geofence-Überwachung besteht darin, die erforderlichen Berechtigungen anzufordern. Wenn Sie Geofencing verwenden möchten, muss Ihre App Folgendes anfordern:
-
ACCESS_FINE_LOCATION
-
ACCESS_BACKGROUND_LOCATION
wenn Ihre App auf Android 10 (API‑Level 29) oder höher ausgerichtet ist
Weitere Informationen zum Anfordern von Standortberechtigungen
Wenn Sie einen BroadcastReceiver
verwenden möchten, um auf Geofence-Übergänge zu warten, fügen Sie ein Element hinzu, das den Dienstnamen angibt. Dieses Element muss ein untergeordnetes Element des
<application>
-Elements sein:
<application android:allowBackup="true"> ... <receiver android:name=".GeofenceBroadcastReceiver"/> <application/>
Für den Zugriff auf die Standort-APIs müssen Sie eine Instanz des Geofencing-Clients erstellen. So stellen Sie eine Verbindung zu Ihrem Client her:
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); }
Geofences erstellen und hinzufügen
Ihre App muss Geofences mit der Builder-Klasse der Location API zum Erstellen von Geofence-Objekten und der Convenience-Klasse zum Hinzufügen von Geofences erstellen und hinzufügen. Außerdem können Sie einen PendingIntent
definieren, wie in diesem Abschnitt beschrieben, um die Intents zu verarbeiten, die von Location Services gesendet werden, wenn Geofence-Übergänge auftreten.
Hinweis:Auf Geräten für einen einzelnen Nutzer gilt ein Limit von 100 Geofences pro App. Auf Geräten für mehrere Nutzer gilt ein Limit von 100 Geofences pro App und Gerätenutzer.
Geofence-Objekte erstellen
Verwenden Sie zuerst
Geofence.Builder
, um einen Geofence zu erstellen und den gewünschten Radius, die Dauer und die Übergangstypen für den Geofence festzulegen. So füllen Sie beispielsweise ein Listenobjekt:
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());
In diesem Beispiel werden Daten aus einer Konstantendatei abgerufen. In der Praxis können Apps Geofences dynamisch auf Grundlage des Standorts des Nutzers erstellen.
Geofences und erste Trigger angeben
Im folgenden Snippet wird die Klasse
GeofencingRequest
und die darin verschachtelte Klasse
GeofencingRequestBuilder
verwendet, um die zu überwachenden Geofences anzugeben und festzulegen, wie zugehörige Geofence-Ereignisse ausgelöst werden:
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(); }
In diesem Beispiel werden zwei Geofence-Trigger verwendet. Der Übergang
GEOFENCE_TRANSITION_ENTER
wird ausgelöst, wenn ein Gerät in einen Geofence eintritt, und der Übergang
GEOFENCE_TRANSITION_EXIT
wird ausgelöst, wenn ein Gerät einen Geofence verlässt. Wenn Sie
INITIAL_TRIGGER_ENTER
angeben, wird den Standortdiensten mitgeteilt, dass
GEOFENCE_TRANSITION_ENTER
ausgelöst werden soll, wenn sich das Gerät bereits innerhalb des Geofence befindet.
In vielen Fällen ist es möglicherweise besser, stattdessen
INITIAL_TRIGGER_DWELL
zu verwenden, wodurch Ereignisse nur ausgelöst werden, wenn der Nutzer innerhalb eines Geofence für eine bestimmte Dauer anhält.
Dieser Ansatz kann dazu beitragen, „Benachrichtigungs-Spam“ zu reduzieren, der durch eine große Anzahl von Benachrichtigungen entsteht, wenn ein Gerät kurzzeitig in Geofences ein- und ausfährt. Eine weitere Strategie, um die besten Ergebnisse mit Ihren Geofences zu erzielen, besteht darin, einen Mindestradius von 100 Metern festzulegen. So wird die Standortgenauigkeit typischer WLANs berücksichtigt und der Stromverbrauch des Geräts gesenkt.
Broadcast-Empfänger für Geofence-Übergänge definieren
Ein von Location Services gesendeter Intent
kann verschiedene Aktionen in Ihrer App auslösen. Sie sollten damit jedoch keine Aktivität oder kein Fragment starten, da Komponenten nur als Reaktion auf eine Nutzeraktion sichtbar werden sollten. In vielen Fällen ist ein BroadcastReceiver
eine gute Möglichkeit, einen Geofence-Übergang zu verarbeiten. Ein BroadcastReceiver
wird aktualisiert, wenn ein Ereignis eintritt, z. B. wenn ein Geofence betreten oder verlassen wird, und kann lang andauernde Hintergrundaufgaben starten.
Das folgende Snippet zeigt, wie ein PendingIntent
definiert wird, mit dem ein BroadcastReceiver
gestartet wird:
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; }
Geofences hinzufügen
Verwenden Sie die Methode
, um Geofences hinzuzufügen.
Geben Sie das Objekt GeofencingClient.addGeofences()
GeofencingRequest
und PendingIntent
an.
Das folgende Snippet zeigt, wie die Ergebnisse verarbeitet werden:
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 // ... } });
Geofence-Übergänge verarbeiten
Wenn die Standortdienste erkennen, dass der Nutzer einen Geofence betreten oder verlassen hat, wird die Intent
gesendet, die in der PendingIntent
enthalten ist, die Sie in die Anfrage zum Hinzufügen von Geofences aufgenommen haben. Ein Broadcast-Receiver wie GeofenceBroadcastReceiver
bemerkt, dass Intent
aufgerufen wurde, und kann dann das Geofencing-Ereignis aus dem Intent abrufen, den Typ der Geofence-Übergänge ermitteln und feststellen, welcher der definierten Geofences ausgelöst wurde. Der Broadcast-Empfänger kann eine App anweisen, Hintergrundaufgaben auszuführen oder, falls gewünscht, eine Benachrichtigung als Ausgabe zu senden.
Hinweis:Unter Android 8.0 (API-Level 26) und höher reagiert das Gerät alle paar Minuten auf Geofencing-Ereignisse, wenn eine App im Hintergrund ausgeführt wird und gleichzeitig ein Geofence überwacht. Informationen dazu, wie Sie Ihre App an diese Antwortlimits anpassen können, finden Sie unter Einschränkungen für den Hintergrundstandort.
Das folgende Snippet zeigt, wie Sie einen BroadcastReceiver
definieren, der eine Benachrichtigung sendet, wenn ein Geofence-Übergang erfolgt. Wenn der Nutzer auf die Benachrichtigung klickt, wird die Hauptaktivität der App angezeigt:
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)); } } }
Nachdem das Übergangsereignis über PendingIntent
erkannt wurde, ruft BroadcastReceiver
den Geofence-Übergangstyp ab und prüft, ob es sich um eines der Ereignisse handelt, die von der App zum Auslösen von Benachrichtigungen verwendet werden – in diesem Fall entweder GEOFENCE_TRANSITION_ENTER
oder GEOFENCE_TRANSITION_EXIT
. Der Dienst sendet dann eine Benachrichtigung und protokolliert die Übergangsdetails.
Geofence-Überwachung beenden
Wenn Sie die Geofence-Überwachung beenden, wenn sie nicht mehr benötigt oder gewünscht wird, können Sie den Akku und die CPU-Zyklen des Geräts schonen. Sie können das Geofence-Monitoring in der Hauptaktivität beenden, mit der Geofences hinzugefügt und entfernt werden. Wenn Sie einen Geofence entfernen, wird das Monitoring sofort beendet. Die API bietet Methoden zum Entfernen von Geofences entweder anhand von Anforderungs-IDs oder durch Entfernen von Geofences, die mit einem bestimmten PendingIntent
verknüpft sind.
Im folgenden Snippet werden Geofences nach PendingIntent
entfernt. Es werden keine weiteren Benachrichtigungen gesendet, wenn das Gerät in zuvor hinzugefügte Geofences eintritt oder diese verlässt:
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 // ... } });
Sie können Geofencing mit anderen standortbezogenen Funktionen wie regelmäßigen Standortaktualisierungen kombinieren. Weitere Informationen finden Sie in den anderen Lektionen dieses Kurses.
Best Practices für Geofencing verwenden
In diesem Abschnitt finden Sie Empfehlungen für die Verwendung von Geofencing mit den Standort-APIs für Android.
Stromverbrauch senken
Mit den folgenden Methoden können Sie den Stromverbrauch in Ihren Apps optimieren, die Geofencing verwenden:
Stelle die Reaktionsfähigkeit von Benachrichtigungen auf einen höheren Wert ein. Dadurch wird der Stromverbrauch verbessert, da die Latenz von Geofence-Benachrichtigungen erhöht wird. Wenn Sie beispielsweise einen Reaktionsfähigkeitswert von fünf Minuten festlegen, prüft Ihre App nur alle fünf Minuten, ob ein Ein- oder Ausgangsalarm ausgelöst werden soll. Wenn Sie niedrigere Werte festlegen, werden Nutzer nicht unbedingt innerhalb dieses Zeitraums benachrichtigt. Wenn Sie beispielsweise einen Wert von 5 Sekunden festlegen, kann es etwas länger dauern, bis die Benachrichtigung eingeht.
Verwenden Sie einen größeren Geofence-Radius für Orte, an denen sich ein Nutzer längere Zeit aufhält, z. B. zu Hause oder am Arbeitsplatz. Ein größerer Radius verringert zwar nicht direkt den Stromverbrauch, aber die Häufigkeit, mit der die App nach dem Betreten oder Verlassen eines Standorts sucht. Dadurch wird der Gesamtstromverbrauch gesenkt.
Optimalen Radius für Ihren Geofence auswählen
Die besten Ergebnisse erzielen Sie, wenn Sie den Mindestradius des Geofence auf 100 bis 150 Meter festlegen. Wenn WLAN verfügbar ist, liegt die Standortgenauigkeit in der Regel zwischen 20 und 50 Metern. Wenn der Standort in Innenräumen verfügbar ist, kann die Genauigkeit bis zu 5 Meter betragen. Sofern Sie nicht wissen, dass der Standort im Innenbereich innerhalb des Geofence verfügbar ist, gehen Sie davon aus, dass die WLAN-Standortgenauigkeit etwa 50 Meter beträgt.
Wenn der WLAN-Standort nicht verfügbar ist, z. B. wenn Sie in ländlichen Gebieten unterwegs sind, nimmt die Standortgenauigkeit ab. Die Genauigkeit kann zwischen mehreren Hundert Metern und mehreren Kilometern liegen. In solchen Fällen sollten Sie Geofences mit einem größeren Radius erstellen.
Nutzern erklären, warum Ihre App Geofencing verwendet
Da Ihre App im Hintergrund auf den Standort zugreift, wenn Sie Geofencing verwenden, sollten Sie überlegen, wie Ihre App Nutzern Vorteile bietet. Erklären Sie den Nutzern klar, warum Ihre App diesen Zugriff benötigt, um das Verständnis und die Transparenz zu erhöhen.
Weitere Informationen zu Best Practices für den Zugriff auf Standortdaten, einschließlich Geofencing, finden Sie auf der Seite Best Practices für den Datenschutz.
Mit dem Übergangstyp „Verweilen“ die Anzahl von Fehlalarmen reduzieren
Wenn Sie eine große Anzahl von Benachrichtigungen erhalten, wenn Sie kurz an einem Geofence vorbeifahren, können Sie die Anzahl der Benachrichtigungen am besten reduzieren, indem Sie den Übergangstyp
GEOFENCE_TRANSITION_DWELL
anstelle von
GEOFENCE_TRANSITION_ENTER
verwenden. So wird die Benachrichtigung nur gesendet, wenn der Nutzer innerhalb eines Geofence für einen bestimmten Zeitraum anhält. Sie können die Dauer festlegen, indem Sie eine
Verzögerung beim Verweilen einstellen.
Geofences nur bei Bedarf neu registrieren
Registrierte Geofences werden im com.google.process.location
-Prozess gespeichert, der zum com.google.android.gms
-Paket gehört.
Die App muss nichts tun, um die folgenden Ereignisse zu verarbeiten, da das System Geofences nach diesen Ereignissen wiederherstellt:
- Die Google Play-Dienste werden aktualisiert.
- Die Google Play-Dienste werden aufgrund von Ressourcenbeschränkungen vom System beendet und neu gestartet.
- Der Standortprozess stürzt ab.
Die App muss Geofences neu registrieren, wenn sie nach den folgenden Ereignissen noch benötigt werden, da das System die Geofences in den folgenden Fällen nicht wiederherstellen kann:
- Das Gerät wird neu gestartet. Die App sollte auf die Aktion „Boot abgeschlossen“ des Geräts warten und dann die erforderlichen Geofences neu registrieren.
- Die App wird deinstalliert und neu installiert.
- Die Daten der App werden gelöscht.
- Die Daten der Google Play-Dienste werden gelöscht.
- Die App hat eine
GEOFENCE_NOT_AVAILABLE
-Benachrichtigung erhalten. Das passiert in der Regel, nachdem NLP (Android Network Location Provider) deaktiviert wurde.
Fehlerbehebung für das Geofence-Eintrittsereignis
Wenn Geofences nicht ausgelöst werden, wenn das Gerät in einen Geofence eintritt (die
GEOFENCE_TRANSITION_ENTER
-Benachrichtigung wird nicht ausgelöst), prüfen Sie zuerst, ob Ihre Geofences wie in dieser Anleitung beschrieben richtig registriert sind.
Hier sind einige mögliche Gründe dafür, dass Benachrichtigungen nicht wie erwartet funktionieren:
- Der genaue Standort ist innerhalb Ihres Geofence nicht verfügbar oder Ihr Geofence ist zu klein. Auf den meisten Geräten wird für das Auslösen von Geofences nur der Netzwerkstandort verwendet. Der Dienst verwendet diesen Ansatz, weil der Netzwerkstandort viel weniger Strom verbraucht, weniger Zeit benötigt, um diskrete Standorte zu ermitteln, und vor allem in Innenräumen verfügbar ist.
WLAN ist auf dem Gerät deaktiviert. Wenn WLAN aktiviert ist, kann die Standortgenauigkeit erheblich verbessert werden. Wenn WLAN deaktiviert ist, erhält Ihre Anwendung je nach verschiedenen Einstellungen, z. B. dem Radius des Geofence, dem Gerätemodell oder der Android-Version, möglicherweise nie Geofence-Benachrichtigungen. Ab Android 4.3 (API-Level 18) haben wir den „Nur WLAN-Suche“-Modus eingeführt, mit dem Nutzer WLAN deaktivieren und trotzdem eine gute Netzwerkposition erhalten können. Es empfiehlt sich, den Nutzer aufzufordern und ihm eine Verknüpfung zur Verfügung zu stellen, damit er WLAN oder nur den WLAN-Scanmodus aktivieren kann, wenn beide deaktiviert sind. Verwenden Sie SettingsClient, um dafür zu sorgen, dass die Systemeinstellungen des Geräts für eine optimale Standorterkennung richtig konfiguriert sind.
Hinweis : Wenn Ihre App auf Android 10 (API-Level 29) oder höher ausgerichtet ist, können Sie
WifiManager.setEnabled()
nicht direkt aufrufen, es sei denn, Ihre App ist eine System-App oder ein Geräterichtliniencontroller (Device Policy Controller, DPC). Verwenden Sie stattdessen ein Einstellungsfeld.- Innerhalb Ihres Geofence ist keine zuverlässige Netzwerkverbindung verfügbar. Wenn keine zuverlässige Datenverbindung besteht, werden möglicherweise keine Benachrichtigungen generiert. Das liegt daran, dass der Geofence-Dienst vom Netzwerkanbieter für Standortinformationen abhängt, der wiederum eine Datenverbindung benötigt.
- Benachrichtigungen können sich verzögern. Der Geofence-Dienst fragt nicht kontinuierlich den Standort ab. Daher kann es zu einer gewissen Latenz kommen, wenn Sie Benachrichtigungen erhalten. Normalerweise beträgt die Latenz weniger als 2 Minuten, noch weniger, wenn sich das Gerät bewegt hat. Wenn Einschränkungen bei der Standortermittlung im Hintergrund gelten, beträgt die Latenz durchschnittlich 2 bis 3 Minuten. Wenn das Gerät über einen längeren Zeitraum nicht bewegt wurde, kann die Latenz auf bis zu 6 Minuten ansteigen.
Zusätzliche Ressourcen
Weitere Informationen zu Geofencing finden Sie in den folgenden Materialien:
Produktproben
Beispiel-App zum Erstellen und Überwachen von Geofences.