Sie können die WLAN-Standortfunktion der Wi-Fi RTT (Round-Trip-Time) API verwenden, um die Entfernung zu nahe gelegenen RTT-fähigen WLAN-Zugangspunkten und Peer-Wi-Fi Aware-Geräten zu messen.
Wenn Sie die Entfernung zu drei oder mehr Zugangspunkten messen, können Sie mithilfe eines Multilaterationsalgorithmus die Geräteposition schätzen, die am besten zu diesen Messungen passt. Die Genauigkeit des Ergebnisses beträgt in der Regel 1 bis 2 Meter.
Mit dieser Genauigkeit können Sie detaillierte standortbezogene Dienste entwickeln, z. B. die Navigation in Innenräumen, die eindeutige Sprachsteuerung (z. B. „Schalte dieses Licht ein“) und standortbasierte Informationen (z. B. „Gibt es Sonderangebote für dieses Produkt?“).
Das anfordernde Gerät muss sich nicht mit den Zugangspunkten verbinden, um die Entfernung mit WLAN-RTT zu messen. Aus Datenschutzgründen kann nur das anfordernde Gerät die Entfernung zum Zugangspunkt ermitteln. Die Zugangspunkte haben diese Informationen nicht. WLAN-RTT-Vorgänge sind für Apps im Vordergrund unbegrenzt, aber für Apps im Hintergrund gedrosselt.
Wi-Fi-RTT und die zugehörigen Funktionen der Fine-Time-Measurement (FTM) sind im IEEE 802.11-2016-Standard angegeben. WLAN-RTT erfordert die genaue Zeitmessung von FTM, da sie die Entfernung zwischen zwei Geräten berechnet. Dazu wird die Zeit gemessen, die ein Paket für einen Umlauf zwischen den Geräten benötigt, und diese Zeit mit der Lichtgeschwindigkeit multipliziert.
Unterschiede bei der Implementierung je nach Android-Version
WLAN-RTT wurde in Android 9 (API-Level 28) eingeführt. Wenn Sie dieses Protokoll verwenden, um die Position eines Geräts mithilfe von Multilateration mit Geräten mit Android 9 zu bestimmen, benötigen Sie Zugriff auf vordefinierte Zugangspunkt-Standortdaten in Ihrer App. Sie müssen entscheiden, wie diese Daten gespeichert und abgerufen werden.
Auf Geräten mit Android 10 (API-Level 29) und höher können AP-Standortdaten als ResponderLocation
-Objekte dargestellt werden. Dazu gehören unter anderem Breiten-, Längengrad und Höhe. Bei WLAN-RTT-APs, die Location Configuration Information/Location Civic Report (LCI/LCR-Daten) unterstützen, gibt das Protokoll während des Entfernungsprozesses ein ResponderLocation
-Objekt zurück.
Mit dieser Funktion können Apps ZPs direkt nach ihrer Position fragen, anstatt diese Informationen im Voraus speichern zu müssen. Ihre App kann also APs finden und ihre Position bestimmen, auch wenn die AP zuvor noch nicht bekannt waren, z. B. wenn ein Nutzer ein neues Gebäude betritt.
Voraussetzungen
- Die Hardware des Geräts, von dem die Entfernungsanfrage gesendet wird, muss den FTM-Standard 802.11-2016 implementieren.
- Auf dem Gerät, das die Entfernungsanfrage sendet, muss Android 9 (API-Level 28) oder höher installiert sein.
- Auf dem Gerät, das die Entfernungsanfrage sendet, müssen unter Einstellungen > Standort die Standortdienste und die WLAN-Suche aktiviert sein.
- Wenn die App, die die Entfernungsanfrage sendet, auf Android 13 (API-Level 33) oder höher ausgerichtet ist, muss sie die Berechtigung
NEARBY_WIFI_DEVICES
haben. Wenn eine solche App auf eine ältere Android-Version ausgerichtet ist, muss sie stattdessen die BerechtigungACCESS_FINE_LOCATION
haben. - Die App muss den Bereich der Zugangspunkte abfragen, während sie sichtbar ist oder sich in einem Dienst im Vordergrund befindet. Die App kann nicht auf Standortinformationen im Hintergrund zugreifen.
- Der Zugangspunkt muss den IEEE 802.11-2016 FTM-Standard implementieren.
Einrichten
Führen Sie die folgenden Schritte aus, um Ihre App für die Verwendung von WLAN-RTT einzurichten.
1. Berechtigungen anfordern
Fordere im Manifest deiner App die folgenden Berechtigungen an:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- If your app targets Android 13 (API level 33)
or higher, you must declare the NEARBY_WIFI_DEVICES permission. -->
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"
<!-- If your app derives location information from Wi-Fi APIs,
don't include the "usesPermissionFlags" attribute. -->
android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
<!-- If any feature in your app relies on precise location
information, don't include the "maxSdkVersion"
attribute. -->
android:maxSdkVersion="32" />
Die Berechtigungen NEARBY_WIFI_DEVICES
und ACCESS_FINE_LOCATION
sind gefährliche Berechtigungen. Sie müssen sie daher jedes Mal zur Laufzeit anfordern, wenn der Nutzer einen RTT-Scanvorgang ausführen möchte. Ihre App muss die Berechtigung des Nutzers anfordern, wenn die Berechtigung noch nicht erteilt wurde. Weitere Informationen zu Laufzeitberechtigungen finden Sie unter App-Berechtigungen anfordern.
2. Prüfen, ob das Gerät WLAN-RTT unterstützt
Mit der PackageManager API kannst du prüfen, ob das Gerät WLAN-RTT unterstützt:
Kotlin
context.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)
Java
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);
3. Prüfen, ob WLAN-RTT verfügbar ist
Möglicherweise ist auf dem Gerät WLAN-RTT vorhanden, ist aber derzeit nicht verfügbar, weil der Nutzer WLAN deaktiviert hat. Je nach ihren Hardware- und Firmware-Fähigkeiten unterstützen einige Geräte möglicherweise keine WLAN-RTT, wenn SoftAP oder Tethering verwendet werden. Rufen Sie isAvailable() auf, um zu prüfen, ob WLAN-RTT derzeit verfügbar ist.
Die Verfügbarkeit von WLAN-RTT kann sich jederzeit ändern. Deine App sollte einen BroadcastReceiver für den Empfang von ACTION_WIFI_RTT_STATE_CHANGED registrieren, der gesendet wird, wenn sich die Verfügbarkeit ändert. Wenn Ihre App den Broadcast-Intent empfängt, sollte sie den aktuellen Verfügbarkeitsstatus prüfen und ihr Verhalten entsprechend anpassen.
Beispiele:
Kotlin
val filter = IntentFilter(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED) val myReceiver = object: BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (wifiRttManager.isAvailable) { … } else { … } } } context.registerReceiver(myReceiver, filter)
Java
IntentFilter filter = new IntentFilter(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED); BroadcastReceiver myReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (wifiRttManager.isAvailable()) { … } else { … } } }; context.registerReceiver(myReceiver, filter);
Weitere Informationen finden Sie unter Broadcasts.
Eine Entfernungsanfrage erstellen
Eine Entfernungsanfrage (RangingRequest) wird durch Angabe einer Liste von ZPs oder Wi-Fi Aware Peers erstellt, für die ein Bereich angefordert wird. In einer einzelnen Entfernungsanfrage können mehrere Zugangspunkte oder Wi-Fi Aware Peers angegeben werden. Die Entfernungen zu allen Geräten werden gemessen und zurückgegeben.
In einer Anfrage kann beispielsweise mit der Methode addAccessPoint() ein Zugangspunkt angegeben werden, zu dem die Entfernung gemessen werden soll:
Kotlin
val req: RangingRequest = RangingRequest.Builder().run { addAccessPoint(ap1ScanResult) addAccessPoint(ap2ScanResult) build() }
Java
RangingRequest.Builder builder = new RangingRequest.Builder(); builder.addAccessPoint(ap1ScanResult); builder.addAccessPoint(ap2ScanResult); RangingRequest req = builder.build();
Ein Zugangspunkt wird anhand seines ScanResult-Objekts identifiziert, das durch Aufrufen von WifiManager.getScanResults() abgerufen werden kann. Du kannst addAccessPoints(List
In ähnlicher Weise kann bei einer Entfernungsanfrage ein WLAN-sensitiver Peer über seine MAC-Adresse oder sein PeerHandle hinzugefügt werden. Dazu werden die Methoden addWifiAwarePeer(MacAddress Peering) bzw. addWifiAwarePeer(PeerHandle Koppel) verwendet. Weitere Informationen zur Suche nach Wi-Fi Aware-Peers finden Sie in der Wi-Fi Aware-Dokumentation.
Anfragebereich
Eine Anwendung sendet mit der Methode WifiRttManager.startRanging() eine Entfernungsanfrage und stellt Folgendes bereit: einen RangingRequest zur Angabe des Vorgangs, einen Executor zur Angabe des Callback-Kontexts und einen RangingResultCallback zum Empfang der Ergebnisse.
Beispiele:
Kotlin
val mgr = context.getSystemService(Context.WIFI_RTT_RANGING_SERVICE) as WifiRttManager val request: RangingRequest = myRequest mgr.startRanging(request, executor, object : RangingResultCallback() { override fun onRangingResults(results: List<RangingResult>) { … } override fun onRangingFailure(code: Int) { … } })
Java
WifiRttManager mgr = (WifiRttManager) Context.getSystemService(Context.WIFI_RTT_RANGING_SERVICE); RangingRequest request ...; mgr.startRanging(request, executor, new RangingResultCallback() { @Override public void onRangingFailure(int code) { … } @Override public void onRangingResults(List<RangingResult> results) { … } });
Der Entfernungsvorgang wird asynchron ausgeführt und die Entfernungsergebnisse werden in einem der Callbacks von RangingResultCallback zurückgegeben:
- Wenn der gesamte Entfernungsvorgang fehlschlägt, wird der Callback onRangingFailure mit einem Statuscode ausgelöst, der in RangingResultCallback beschrieben wird. Ein solcher Fehler kann auftreten, wenn der Dienst zum entsprechenden Zeitpunkt keinen Bereiching-Vorgang ausführen kann, z. B. weil WLAN deaktiviert ist, die Anwendung zu viele Entfernungsvorgänge angefordert und gedrosselt wurde oder ein Berechtigungsproblem vorliegt.
- Wenn der Entfernungsvorgang abgeschlossen ist, wird der Callback onRangingResults mit einer Liste von Ergebnissen ausgelöst, die mit der Liste der Anfragen übereinstimmt. Dabei handelt es sich um ein Ergebnis für jede Anfrage. Die Reihenfolge der Ergebnisse entspricht nicht unbedingt der Reihenfolge der Anfragen. Der Entfernungsvorgang kann zwar abgeschlossen werden, aber jedes Ergebnis kann dennoch auf einen Fehler bei der jeweiligen Messung hinweisen.
Entfernungsergebnisse interpretieren
Jedes der vom onRangingResults-Callback zurückgegebenen Ergebnisse wird durch ein RangingResult-Objekt angegeben. Gehen Sie bei jeder Anfrage so vor:
1. Anfrage identifizieren
Identifizieren Sie die Anfrage anhand der Informationen, die Sie beim Erstellen der RangingRequest angegeben haben. Dies ist meistens eine MAC-Adresse aus dem ScanResult
, die einen Zugangspunkt identifiziert. Die MAC-Adresse kann mit der Methode getMacAddress() aus dem Entfernungsergebnis abgerufen werden.
Die Liste der Bereichsergebnisse kann in einer anderen Reihenfolge als die Peers (Zugangspunkte) sein, die in der Entfernungsanfrage angegeben sind. Daher sollten Sie zur Identifizierung des Peers und nicht der Reihenfolge der Ergebnisse die MAC-Adresse verwenden.
2. Herausfinden, ob die Messung erfolgreich war
Mit der Methode getStatus() können Sie feststellen, ob eine Messung erfolgreich war. Jeder andere Wert als STATUS_SUCCESS weist auf einen Fehler hin. Ein Fehler bedeutet, dass alle anderen Felder dieses Ergebnisses (mit Ausnahme der oben genannten Anfrageidentifikation) ungültig sind und die entsprechende get*
-Methode mit der Ausnahme IllegalStateException fehlschlägt.
3. Ergebnisse für jede erfolgreiche Messung erhalten
Für jede erfolgreiche Messung können Sie Ergebniswerte mit den jeweiligen get
-Methoden abrufen:
Entfernung in mm und die Standardabweichung der Messung:
RSSI der für die Messungen verwendeten Pakete:
Zeit in Millisekunden, zu der die Messung durchgeführt wurde (angegebene Zeit seit dem Start):
Anzahl der versuchten Messungen und Anzahl der erfolgreich durchgeführten Messungen (und auf denen die Entfernungsmessungen basieren):
Android-Geräte, die WLAN-RTT unterstützen
In den folgenden Tabellen sind einige Telefone, Zugangspunkte und Geräte im Einzelhandel, in Lagern und in Distributionszentren aufgeführt, die WLAN-RTT unterstützen. Diese sind alles andere als umfassend. Wenn Sie Ihre RTT-fähigen Produkte hier auflisten möchten, wenden Sie sich bitte an uns.
Zugangspunkte
Hersteller und Modell | Datum der Unterstützung |
---|---|
Nest Wifi Pro (Wi-Fi 6E) | Unterstützt |
Compulab WILD AP | Unterstützt |
Google Wifi | Unterstützt |
Google Nest-WLAN-Router | Unterstützt |
Google Nest Wifi-Zugangspunkt | Unterstützt |
Aruba AP-635 | Unterstützt |
Cisco 9130 | Unterstützt |
Cisco 9136 | Unterstützt |
Cisco 9166 | Unterstützt |
Cisco 9164 | Unterstützt |
Aruba AP-505 | Unterstützt |
Aruba AP-515 | Unterstützt |
Aruba AP-575 | Unterstützt |
Aruba AP-518 | Unterstützt |
Aruba AP-505H | Unterstützt |
Aruba AP-565 | Unterstützt |
Aruba AP-535 | Unterstützt |
Smartphones
Hersteller und Modell | Android-Version |
---|---|
Google Pixel 6 | 9,0 oder höher |
Google Pixel 6 Pro | 9,0 oder höher |
Google Pixel 5 | 9,0 oder höher |
Pixel 5a | 9,0 oder höher |
Pixel 5a (5G) | 9,0 oder höher |
Xiaomi Mi 10 Pro | 9,0 oder höher |
Xiaomi Mi 10 | 9,0 oder höher |
Xiaomi Redmi Mi 9T Pro | 9,0 oder höher |
Xiaomi Mi 9T | 9,0 oder höher |
Xiaomi Mi 9 | 9,0 oder höher |
Xiaomi Mi Note 10 | 9,0 oder höher |
Xiaomi Mi Note 10 Lite | 9,0 oder höher |
Xiaomi Redmi Note 9S | 9,0 oder höher |
Xiaomi Redmi Note 9 Pro | 9,0 oder höher |
Xiaomi Redmi Note 8T | 9,0 oder höher |
Xiaomi Redmi Note 8 | 9,0 oder höher |
Xiaomi Redmi K30 Pro | 9,0 oder höher |
Xiaomi Redmi K20 Pro | 9,0 oder höher |
Xiaomi Redmi K20 | 9,0 oder höher |
Xiaomi Redmi Note 5 Pro | 9,0 oder höher |
Xiaomi Mi CC9 Pro | 9,0 oder höher |
LG G8X ThinQ | 9,0 oder höher |
LG V50S ThinQ | 9,0 oder höher |
LG V60 ThinQ | 9,0 oder höher |
LG V30 | 9,0 oder höher |
Samsung Galaxy Note 10+ 5G | 9,0 oder höher |
Samsung Galaxy S20+ 5G | 9,0 oder höher |
Samsung Galaxy S20+ | 9,0 oder höher |
Samsung Galaxy S20 5G | 9,0 oder höher |
Samsung Galaxy S20 Ultra 5G | 9,0 oder höher |
Samsung Galaxy S20 | 9,0 oder höher |
Samsung Galaxy Note 10+ | 9,0 oder höher |
Samsung Galaxy Note 10 5G | 9,0 oder höher |
Samsung Galaxy Note 10 | 9,0 oder höher |
Samsung A9 Pro | 9,0 oder höher |
Google Pixel 4 XL | 9,0 oder höher |
Google Pixel 4 | 9,0 oder höher |
Google Pixel 4a | 9,0 oder höher |
Google Pixel 3 XL | 9,0 oder höher |
Google Pixel 3 | 9,0 oder höher |
Google Pixel 3a XL | 9,0 oder höher |
Google Pixel 3a | 9,0 oder höher |
Google Pixel 2 XL | 9,0 oder höher |
Google Pixel 2 | 9,0 oder höher |
Google Pixel 1 XL | 9,0 oder höher |
Google Pixel 1 | 9,0 oder höher |
Poco X2 | 9,0 oder höher |
Sharp Aquos R3 SH-04L | 9,0 oder höher |
Geräte für Einzelhandel, Lagerung und Distributionszentrum
Hersteller und Modell | Android-Version |
---|---|
Zebra PS20 | 10+ |
Zebra TC52/TC52HC | 10+ |
Zebra TC57 | 10+ |
Zebra TC72 | 10+ |
Zebra TC77 | 10+ |
Zebra MC93 | 10+ |
Zebra TC8300 | 10+ |
Zebra VC8300 | 10+ |
Zebra EC30 | 10+ |
Zebra ET51 | 10+ |
Zebra ET56 | 10+ |
Zebra L10 | 10+ |
Zebra CC600/CC6000 | 10+ |
Zebra MC3300x | 10+ |
Zebra MC330x | 10+ |
Zebra TC52x | 10+ |
Zebra TC57x | 10+ |
Zebra EC50 (LAN und HC) | 10+ |
Zebra EC55 (WAN) | 10+ |
Zebra WT6300 | 10+ |
Skorpio X5 | 10+ |