Beim Geofencing wird der aktuelle Standort des Nutzers mit seiner Nähe zu Orten kombiniert, die für ihn interessant sein könnten. Geben Sie den Breiten- und Längengrad an, um einen POI zu markieren. Um die Nähe zum Standort anzupassen, fügen Sie einen Umkreis hinzu. Mithilfe von Breiten- und Längengrad sowie Radius wird ein Geofence definiert, also ein kreisförmiger Bereich um den gewünschten Standort.
Sie können mehrere aktive Geofences haben, mit einem Limit von 100 pro App und pro Gerätenutzer. Für jeden Geofence können Sie die Standortdienste bitten, Ihnen Betretens- und Verlassensereignisse zu senden. Sie können auch eine Dauer innerhalb des Geofence-Bereichs angeben, die gewartet werden soll, bevor ein Ereignis ausgelöst wird (Wartezeit). Sie können die Dauer eines Geofences begrenzen, indem Sie eine Ablaufzeit in Millisekunden angeben. Nach Ablauf des Geofences wird er von den Standortdiensten automatisch entfernt.
In dieser Lektion erfahren Sie, wie Sie Geofences hinzufügen und entfernen und dann mit einer BroadcastReceiver
auf Geofence-Übergänge warten.
Hinweis:Auf Wear-Geräten werden die Geofencing APIs nicht effizient genutzt. Wir empfehlen diese APIs nicht für Wear. Weitere Informationen finden Sie unter Energie und Akku schonen.
Einrichtung für die Geofence-Überwachung
Der erste Schritt beim Anfordern der Geofence-Überwachung besteht darin, die erforderlichen Berechtigungen anzufordern. Damit Sie Geofencing verwenden können, 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 finden Sie in der Anleitung zum Anfordern von Berechtigungen zur Standortermittlung.
Wenn Sie mit BroadcastReceiver
auf Geofence-Übergänge warten möchten, fügen Sie ein Element mit dem Dienstnamen hinzu. Dieses Element muss ein untergeordnetes Element des Elements
<application>
sein:
<application android:allowBackup="true"> ... <receiver android:name=".GeofenceBroadcastReceiver"/> <application/>
Wenn Sie auf die Standort-APIs zugreifen möchten, 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 mithilfe der Builder-Klasse der Standort-API zum Erstellen von Geofence-Objekten und der Convenience-Klasse zum Hinzufügen von Geofences erstellen und hinzufügen. Wenn Sie die von den Standortdiensten gesendeten Intents bei Geofence-Übergängen verarbeiten möchten, können Sie wie in diesem Abschnitt gezeigt eine PendingIntent
definieren.
Hinweis:Auf Geräten mit nur einem Nutzer ist die Anzahl der Geofences pro App auf 100 beschränkt. Auf Geräten mit mehreren Nutzern ist die Anzahl der Geofences pro App und Nutzer auf 100 beschränkt.
Geofence-Objekte erstellen
Erstellen Sie zuerst mit
Geofence.Builder
einen Geofence und legen Sie den gewünschten Radius, die Dauer und die Übergangstypen für den Geofence fest. 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 Anwendungen Geofences basierend auf dem Standort des Nutzers dynamisch erstellen.
Geofences und erste Trigger angeben
Im folgenden Snippet werden die Klasse
GeofencingRequest
und die 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. Die
GEOFENCE_TRANSITION_ENTER
-Übergang wird ausgelöst, wenn ein Gerät einen Geofence betritt, und die
GEOFENCE_TRANSITION_EXIT
-Übergang 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 im Geofence befindet.
In vielen Fällen ist es besser, stattdessen
INITIAL_TRIGGER_DWELL
zu verwenden. Damit werden Ereignisse nur ausgelöst, wenn sich der Nutzer für eine bestimmte Dauer innerhalb eines Geofences aufhält.
Mit diesem Ansatz können Sie „Benachrichtigungs-Spam“ reduzieren, der bei einer großen Anzahl von Benachrichtigungen entsteht, wenn ein Gerät einen Geofences kurzzeitig betreten und beenden. Eine weitere Strategie, um die besten Ergebnisse mit Ihren Geofences zu erzielen, besteht darin, einen Mindestradius von 100 Metern festzulegen. Dies trägt dazu bei, die Standortgenauigkeit typischer WLAN-Netzwerke zu berücksichtigen und den Stromverbrauch der Geräte zu senken.
Broadcast-Empfänger für Geofence-Übergänge definieren
Ein von den Standortdiensten gesendetes Intent
kann verschiedene Aktionen in Ihrer App auslösen. Sie sollten jedoch nicht eine Aktivität oder ein Fragment damit starten, da Komponenten nur als Reaktion auf eine Nutzeraktion sichtbar werden sollten. In vielen Fällen ist eine BroadcastReceiver
eine gute Möglichkeit, einen Geofence-Übergang zu verarbeiten. Ein BroadcastReceiver
wird aktualisiert, wenn ein Ereignis eintritt, z. B. ein Wechsel in einen oder aus einem Geofence, und kann mit lang andauernden Hintergrundarbeiten beginnen.
Das folgende Snippet zeigt, wie ein PendingIntent
definiert wird, das ein BroadcastReceiver
startet:
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 GeofencingClient.addGeofences()
GeofencingRequest
-Objekt und die PendingIntent
an.
Das folgende Snippet zeigt die Verarbeitung der Ergebnisse:
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 der Anfrage zum Hinzufügen von Geofences angegeben haben. Ein Broadcast-Empfänger wie GeofenceBroadcastReceiver
erkennt, dass Intent
aufgerufen wurde, und kann dann das Geofencing-Ereignis aus dem Intent abrufen, die Art der Geofence-Übergänge bestimmen und ermitteln, welcher der definierten Geofences ausgelöst wurde. Der Empfänger der Übertragung kann eine App anweisen, Hintergrundarbeiten auszuführen oder, falls gewünscht, eine Benachrichtigung als Ausgabe senden.
Hinweis:Wenn unter Android 8.0 (API-Level 26) und höher eine App im Hintergrund ausgeführt wird, während ein Geofence überwacht wird, reagiert das Gerät alle paar Minuten auf Geofence-Ereignisse. Informationen dazu, wie Sie Ihre App an diese Antwortlimits anpassen, finden Sie unter Standortlimits im Hintergrund.
Das folgende Snippet zeigt, wie ein BroadcastReceiver
definiert wird, mit dem bei einem Geofence-Übergang eine Benachrichtigung gesendet wird. 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 testet, ob es sich um eines der Ereignisse handelt, die die Anwendung zum Auslösen von Benachrichtigungen verwendet – in diesem Fall GEOFENCE_TRANSITION_ENTER
oder GEOFENCE_TRANSITION_EXIT
. Der Dienst sendet dann eine Benachrichtigung und protokolliert die Details zur Umstellung.
Geofence-Monitoring 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. Durch das Entfernen eines Geofence wird es sofort gestoppt. Die API bietet Methoden zum Entfernen von Geofences, entweder anhand von Anfrage-IDs oder durch Entfernen von Geofences, die mit einer bestimmten PendingIntent
verknüpft sind.
Im folgenden Snippet werden Geofences von PendingIntent
entfernt. Dadurch werden alle weiteren Benachrichtigungen verhindert, wenn das Gerät zuvor hinzugefügte Geofences betritt oder 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 standortbasierten Funktionen kombinieren, z. B. mit regelmäßigen Standortaktualisierungen. 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.
Energieverbrauch reduzieren
Mit den folgenden Methoden können Sie den Stromverbrauch in Apps mit Geofencing optimieren:
Legen Sie für die Benachrichtigungsreaktion einen höheren Wert fest. Dadurch wird der Stromverbrauch optimiert, da die Latenz von Geofence-Benachrichtigungen erhöht wird. Wenn Sie beispielsweise einen Wert von fünf Minuten festlegen, prüft Ihre App nur alle fünf Minuten, ob eine Benachrichtigung für den Betreten oder Verlassen des Gebäudes erforderlich ist. Wenn Sie niedrigere Werte festlegen, bedeutet das nicht unbedingt, dass Nutzer innerhalb dieses Zeitraums benachrichtigt werden. Wenn Sie beispielsweise einen Wert von 5 Sekunden festlegen, kann es etwas länger dauern, bis die Benachrichtigung empfangen wird.
Verwenden Sie einen größeren Geofence-Radius für Orte, an denen Nutzer viel Zeit verbringen, z. B. zu Hause oder bei der Arbeit. Ein größerer Radius reduziert zwar nicht direkt den Energieverbrauch, aber die Häufigkeit, mit der die App nach Ein- oder Ausfahrten sucht. Dadurch wird der Gesamtenergieverbrauch effektiv gesenkt.
Optimalen Radius für Ihr Geofence auswählen
Die besten Ergebnisse erzielen Sie, wenn der Mindestradius des Geofences zwischen 100 und 150 Metern liegt. Wenn WLAN verfügbar ist, liegt die Standortgenauigkeit in der Regel zwischen 20 und 50 Metern. Wenn die Standortermittlung in Innenräumen verfügbar ist, kann die Genauigkeit bis zu 5 Meter betragen. Sofern Sie nicht wissen, ob die Standortermittlung in Innenräumen innerhalb des Geofences verfügbar ist, gehen Sie davon aus, dass die WLAN-Standortgenauigkeit etwa 50 Meter beträgt.
Wenn die WLAN-Standortermittlung nicht verfügbar ist (z. B. wenn Sie in ländlichen Gebieten fahren), ist die Standortgenauigkeit geringer. Die Genauigkeit kann mehrere hundert Meter bis mehrere Kilometer betragen. In solchen Fällen sollten Sie Geofences mit einem größeren Radius erstellen.
Erläutern Sie Nutzern, warum Ihre App Geofencing verwendet
Da Ihre App bei der Verwendung von Geofencing im Hintergrund auf den Standort zugreift, sollten Sie überlegen, welche Vorteile sie für Nutzer bietet. Erkläre ihnen klar, warum deine App diesen Zugriff benötigt, um für mehr Verständnis und Transparenz zu sorgen.
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.
Den Verweildauer-Übergangstyp verwenden, um Benachrichtigungsspam zu 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 sich der Nutzer für einen bestimmten Zeitraum innerhalb eines Geofences aufhält. Sie können die Dauer festlegen, indem Sie eine
Loitering-Verzögerung festlegen.
Geofences nur bei Bedarf neu registrieren
Registrierte Geofences werden im com.google.process.location
-Prozess gespeichert, der dem com.google.android.gms
-Paket zugewiesen ist.
Für die folgenden Ereignisse muss die App nichts tun, da das System Geofences nach diesen Ereignissen wiederherstellt:
- Die Google Play-Dienste werden aktualisiert.
- Die Google Play-Dienste werden aufgrund von Ressourceneinschränkungen vom System beendet und neu gestartet.
- Der Standortprozess stürzt ab.
Die Anwendung 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 complete“ 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
Warnung erhalten. Das passiert in der Regel, nachdem NLP (Network Location Provider, Android-Netzwerkstandortanbieter) deaktiviert ist.
Fehlerbehebung für das Geofence-Ereignis „Eintritt“
Wenn Geofences nicht ausgelöst werden, wenn das Gerät einen Geofence betritt (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:
- Innerhalb Ihres Geofences ist kein genauer Standort verfügbar oder Ihr Geofence ist zu klein. Auf den meisten Geräten verwendet der Geofence-Dienst nur den Netzwerkstandort für die Geofence-Triggerung. Der Dienst verwendet diesen Ansatz, da die Standortermittlung über das Netzwerk viel weniger Strom verbraucht, weniger Zeit für die Ermittlung einzelner Standorte benötigt wird und vor allem auch drinnen funktioniert.
WLAN ist auf dem Gerät deaktiviert. Wenn das WLAN aktiviert ist, kann die Standortgenauigkeit erheblich verbessert werden. Wenn das WLAN deaktiviert ist, erhält Ihre App je nach verschiedenen Einstellungen, z. B. dem Radius des Geofences, dem Gerätemodell oder der Android-Version, möglicherweise nie Geofence-Benachrichtigungen. Ab Android 4.3 (API-Level 18) haben wir den Modus „Nur WLAN-Scan“ hinzugefügt. Damit können Nutzer WLAN deaktivieren und trotzdem einen guten Netzwerkstandort erhalten. Es hat sich bewährt, den Nutzer aufzufordern und ihm eine Verknüpfung zu geben, mit der er den WLAN- oder WLAN-Scanmodus aktivieren kann, wenn beide deaktiviert sind. Mit SettingsClient können Sie prüfen, ob 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()
nur dann direkt aufrufen, wenn es sich um eine System-App oder einen Geräterichtliniencontroller (Device Policy Controller, DPC) handelt. Verwenden Sie stattdessen einen Einstellungsbereich.- Innerhalb Ihres Geofences gibt es keine zuverlässige Netzwerkverbindung. Wenn keine zuverlässige Datenverbindung besteht, werden möglicherweise keine Benachrichtigungen generiert. Das liegt daran, dass der Geofence-Dienst vom Netzwerkstandortanbieter abhängt, der wiederum eine Datenverbindung benötigt.
- Benachrichtigungen können sich verspäten. Der Geofence-Dienst fragt nicht kontinuierlich den Standort ab. Daher kann es beim Empfang von Benachrichtigungen zu Verzögerungen kommen. Normalerweise beträgt die Latenz weniger als 2 Minuten, bei Bewegung des Geräts sogar weniger. Wenn Einschränkungen bei der Standortermittlung im Hintergrund gelten, beträgt die Latenz durchschnittlich 2 bis 3 Minuten. Wenn das Gerät längere Zeit nicht aktiv war, kann sich die Latenz erhöhen (bis zu 6 Minuten).
Weitere Informationen
Weitere Informationen zu Geofencing finden Sie in den folgenden Dokumenten:
Produktproben
Exemplarische App zum Erstellen und Überwachen von Geofences.