Mit der WLAN-Standortfunktion der Wi‑Fi RTT (Round-Trip-Time) API können Sie die Entfernung zu RTT-fähigen WLAN-Zugangspunkten und Wi‑Fi Aware-Geräten in der Nähe messen.
Wenn Sie die Entfernung zu drei oder mehr Zugangspunkten messen, können Sie mit einem Multilateration-Algorithmus die Geräteposition schätzen, die am besten zu diesen Messungen passt. Das Ergebnis ist in der Regel auf 1–2 Meter genau.
Mit dieser Genauigkeit können Sie detaillierte standortbasierte Dienste entwickeln, z. B. Indoor-Navigation, eine eindeutige Sprachsteuerung (z. B. „Schalte diese Lampe ein“) und standortbasierte Informationen (z. B. „Gibt es Sonderangebote für dieses Produkt?“).
Das anfragende Gerät muss sich nicht mit den Zugangspunkten verbinden, um die Entfernung mithilfe von WLAN-RTT zu messen. Aus Datenschutzgründen kann nur das anfordernde Gerät die Entfernung zum Zugangspunkt ermitteln. Diese Informationen fehlen an den Zugangspunkten. Wi‑Fi-RTT-Vorgänge sind für Apps im Vordergrund unbegrenzt, für Apps im Hintergrund jedoch gedrosselt.
Wi‑Fi-RTT und die zugehörigen FTM-Funktionen (Fine-Time-Measurement) sind im IEEE 802.11-2016-Standard spezifiziert. Für die Wi‑Fi-RTT ist die genaue Zeitmessung von FTM erforderlich, da die Entfernung zwischen zwei Geräten berechnet wird, indem die Zeit gemessen wird, die ein Paket für einen Hin- und Rückweg zwischen den Geräten benötigt, und diese Zeit mit der Lichtgeschwindigkeit multipliziert wird.
Mit Android 15 (API-Level 35) wurde die Unterstützung für die nicht triggerbasierte (NTB) Entfernungsmessung nach IEEE 802.11az eingeführt.
Implementierungsunterschiede je nach Android-Version
WLAN-RTT wurde mit Android 9 (API-Level 28) eingeführt. Wenn Sie dieses Protokoll verwenden, um den Standort eines Geräts mithilfe von Multilateration mit Geräten mit Android 9 zu ermitteln, benötigen Sie Zugriff auf vorab festgelegte Standortdaten von Zugangspunkten (Access Points, APs) in Ihrer App. Sie entscheiden selbst, wie Sie diese Daten speichern und abrufen.
Auf Geräten mit Android 10 (API-Level 29) und höher können Standortdaten von Zugangspunkten als ResponderLocation
-Objekte dargestellt werden, die geografische Breite, geografische Länge und Höhe enthalten. Bei WLAN-RTT-Zugangspunkten, die LCI-/LCR-Daten (Location Configuration Information/Location Civic Report) unterstützen, gibt das Protokoll während des Abstandsbestimmungsverfahrens ein ResponderLocation
-Objekt zurück.
Mit dieser Funktion können Apps ZPs direkt nach ihrer Position fragen, anstatt diese Informationen vorab speichern zu müssen. So kann Ihre App ZPs finden und ihre Positionen bestimmen, auch wenn die ZPs vorher nicht bekannt waren, z. B. wenn ein Nutzer ein neues Gebäude betritt.
Die Unterstützung für IEEE 802.11az NTB-Range-Range ist auf Geräten mit Android 15 (API-Level 35) und höher verfügbar. Wenn das Gerät den IEEE 802.11az-NTB-Initiatormodus unterstützt (WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_NTB_INITIATOR
), kann Ihre App mit einer einzigen Reichweitesanfrage sowohl IEEE 802.11mc- als auch IEEE 802.11az-kompatible ZPs finden. Die RangingResult
API wurde um Informationen zum Mindest- und Höchstwert erweitert, der für das Intervall zwischen den Messwerten verwendet werden kann. Das genaue Intervall wird von Ihrer App gesteuert.
Voraussetzungen
- Auf der Hardware des Geräts, von dem die Entfernungsanfrage gesendet wird, muss der FTM-Standard 802.11-2016 oder der Standard 802.11az (nicht triggerbasierte Bereichserkennung) implementiert werden.
- Auf dem Gerät, das die Anfrage sendet, muss Android 9 (API-Ebene 28) oder höher installiert sein. Die nicht triggerbasierte Entfernungsmessung nach IEEE 802.11az ist auf Geräten mit Android 15 (API-Level 35) und höher aktiviert.
- Auf dem Gerät, das die Anfrage sendet, müssen die Standortdienste und die WLAN-Suche aktiviert sein (unter Einstellungen > Standort).
- Wenn die App, die die Anfrage für die Standortermittlung 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 frühere Android-Version ausgerichtet ist, muss sie stattdessen die BerechtigungACCESS_FINE_LOCATION
haben. - Die App muss den Bereich der Zugangspunkte abfragen, während die App sichtbar ist oder sich in einem Dienst im Vordergrund befindet. Die App kann nicht im Hintergrund auf Standortinformationen zugreifen.
- Der Zugangspunkt muss den FTM-Standard IEEE 802.11-2016 oder den Standard IEEE 802.11az (nicht triggerbasiertes Ranging) implementieren.
Einrichten
So richten Sie Ihre App für die Verwendung von WLAN-RTT ein:
1. Berechtigungen anfordern
Fordern Sie die folgenden Berechtigungen im Manifest Ihrer App 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 also jedes Mal zur Laufzeit anfordern, wenn der Nutzer einen RTT-Scan ausführen möchte. Ihre App muss die Berechtigung des Nutzers anfordern, wenn diese nicht bereits 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 können Sie 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. Verfügbarkeit von WLAN-RTT prüfen
WLAN-RTT ist möglicherweise auf dem Gerät vorhanden, aber möglicherweise nicht verfügbar, weil der Nutzer WLAN deaktiviert hat. Je nach Hardware- und Firmwarefunktionen unterstützen einige Geräte möglicherweise keine WLAN-RTT-Funktion, wenn SoftAP oder Tethering verwendet werden. Wenn Sie prüfen möchten, ob WLAN-RTT verfügbar ist, rufen Sie isAvailable()
auf.
Die Verfügbarkeit von WLAN-RTT kann sich jederzeit ändern. Ihre App sollte einen BroadcastReceiver
registrieren, um ACTION_WIFI_RTT_STATE_CHANGED
zu empfangen, das gesendet wird, wenn sich die Verfügbarkeit ändert. Wenn Ihre App die Broadcastabsicht empfängt, sollte sie den aktuellen Verfügbarkeitsstatus prüfen und ihr Verhalten entsprechend anpassen.
Beispiel:
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 Übertragungen.
Bereichsabfrage erstellen
Eine Anfrage für die Standortermittlung (RangingRequest
) wird erstellt, indem eine Liste von ZPs oder Wi‑Fi Aware-Peers angegeben wird, für die eine Standortermittlung 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 durch sein ScanResult
-Objekt identifiziert, das durch Aufrufen von WifiManager.getScanResults()
abgerufen werden kann.
Mit addAccessPoints(List<ScanResult>)
können Sie mehrere Zugangspunkte gleichzeitig hinzufügen.
ScanResult
-Objekte können sowohl von IEEE 802.11mc (is80211mcResponder()
) als auch von IEEE 802.11az (is80211azNtbResponder()
) unterstützte ZPs mit nicht triggerbasierter Entfernungsmessung enthalten. Geräte, die IEEE 802.11az-NTB-Messungen unterstützen, führen je nach den Fähigkeiten des ZP entweder 802.11mc- oder 802.11az-Messungen durch. Standardmäßig wird 802.11az verwendet, wenn der ZP beide unterstützt. Geräte, die IEEE 802.11az nicht unterstützen, führen alle Abfragen mit dem IEEE 802.11mc-Protokoll durch.
Ebenso kann bei einer Abfrage ein Wi‑Fi Aware-Peer entweder über seine MAC-Adresse oder seine PeerHandle
hinzugefügt werden, und zwar mit den Methoden addWifiAwarePeer(MacAddress peer)
und addWifiAwarePeer(PeerHandle peer)
. Weitere Informationen zum Auffinden von Wi‑Fi Aware-Peers finden Sie in der Wi‑Fi Aware-Dokumentation.
Bereichsauswahl anfordern
Eine App sendet eine Abfrage mit der Methode WifiRttManager.startRanging()
und gibt Folgendes an: RangingRequest
, um den Vorgang anzugeben, Executor
, um den Callback-Kontext anzugeben, und RangingResultCallback
, um die Ergebnisse zu empfangen.
Beispiel:
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 Abtastvorgang wird asynchron ausgeführt und die Ergebnisse werden in einem der Callbacks von RangingResultCallback
zurückgegeben:
- Wenn der gesamte Bereichserkennungsvorgang fehlschlägt, wird der
onRangingFailure
-Callback mit einem Statuscode ausgelöst, der inRangingResultCallback
beschrieben wird. Ein solcher Fehler kann auftreten, wenn der Dienst zu diesem Zeitpunkt keinen Bereiching-Vorgang ausführen kann. Dies kann beispielsweise der Fall sein, wenn WLAN deaktiviert ist, die Anwendung zu viele Bereichserkennungsvorgänge angefordert hat und gedrosselt wird oder wenn ein Berechtigungsproblem vorliegt. - Wenn der Abfragevorgang abgeschlossen ist, wird der Callback
onRangingResults
mit einer Liste von Ergebnissen ausgelöst, die der Liste der Anfragen entspricht – ein Ergebnis für jede Anfrage. Die Reihenfolge der Ergebnisse stimmt nicht unbedingt mit der Reihenfolge der Anfragen überein. Beachten Sie, dass der Abtastvorgang zwar abgeschlossen sein kann, jedes Ergebnis jedoch weiterhin auf einen Fehler bei dieser bestimmten Messung hinweisen kann.
Bereichsergebnisse 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 beim Erstellen der RangingRequest
angegeben wurden: Meistens ist dies eine MAC-Adresse im ScanResult
, die einen Zugangspunkt identifiziert. Die MAC-Adresse kann mit der Methode getMacAddress()
aus dem Ergebnis der Entfernungsmessung abgerufen werden.
Die Liste der Ergebnisse der Standortbestimmung kann sich von der Reihenfolge der in der Standortbestimmungsanfrage angegebenen Peers (Zugangspunkte) unterscheiden. Verwenden Sie daher die MAC-Adresse, um den Peer zu identifizieren, und nicht die Reihenfolge der Ergebnisse.
2. Prüfen, ob jede Messung erfolgreich war
Verwenden Sie die Methode getStatus()
, um festzustellen, 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 Anfrage-ID oben) ungültig sind und die entsprechende get*
-Methode mit einer IllegalStateException
-Ausnahme fehlschlägt.
3. Ergebnisse für jede erfolgreiche Messung abrufen
Für jede erfolgreiche Messung (RangingResult
) können Sie mit den entsprechenden get
-Methoden Ergebniswerte abrufen:
Entfernung in mm und Standardabweichung des Messwerts:
RSSI der für die Messungen verwendeten Pakete:
Zeit in Millisekunden, zu der die Messung durchgeführt wurde (Zeitangabe seit dem Start):
Anzahl der versuchten und der erfolgreichen Messungen, auf denen die Entfernungsmessungen basieren:
Mindest- und Höchstzeit, die ein Clientgerät zwischen zwei 11az-NTB-Messungen warten muss:
getMinTimeBetweenNtbMeasurementsMicros()
undgetMaxTimeBetweenNtbMeasurementsMicros()
geben die minimale und maximale Zeit zurück. Wenn die nächste Bereichsmessung vor Ablauf der Mindestzeit angefordert wird, gibt die API das im Cache gespeicherte Ergebnis der Entfernungsbestimmung zurück. Wenn die nächste Entfernungsmessung nach Ablauf der maximalen Zeit angefordert wird, beendet die API die Entfernungsmessung ohne Trigger und verhandelt eine neue Entfernungsmessung mit der antwortenden Station. Sie sollten keine neue Positionsermittlung anfordern, da dies die Zeit für die Positionsermittlung verlängert. Wenn Sie die Effizienz der nicht triggerbasierten 802.11az-Messung voll ausschöpfen möchten, lösen Sie die nächste Anfrage für die Entfernungsmessung zwischen der minimalen und maximalen Messzeit aus, die in der vorherigenRangingResult
-Messung angegeben wurde.Wiederholungen des Long Training Field (LTF), die von Responder- und Initiatorstationen in der Präambel für das IEEE 802.11az-NTB verwendet werden, führen zu:
Anzahl der übertragenen und empfangenen Spatial Time Streams (STS), die die Initiatorstation für das IEEE 802.11az-NTB-Ergebnis verwendet hat:
Android-Geräte, die WiFi-RTT unterstützen
In den folgenden Tabellen sind einige Smartphones, Zugangspunkte sowie Geräte in den Bereichen Einzelhandel, Warehousing und Distribution Center aufgeführt, die WLAN-RTT unterstützen. Diese sind bei weitem nicht vollständig. Wir empfehlen Ihnen, sich an uns zu wenden, um Ihre RTT-fähigen Produkte hier aufzulisten.
Zugangspunkte
Hersteller und Modell | Supportdatum |
---|---|
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 |
---|---|
Pixel 6 | 9.0+ |
Pixel 6 Pro | 9.0+ |
Pixel 5 | 9.0+ |
Pixel 5a | 9.0+ |
Pixel 5a (5G) | 9.0+ |
Xiaomi Mi 10 Pro | 9.0+ |
Xiaomi Mi 10 | 9.0+ |
Xiaomi Redmi Mi 9T Pro | 9.0+ |
Xiaomi Mi 9T | 9.0+ |
Xiaomi Mi 9 | 9.0+ |
Xiaomi Mi Note 10 | 9.0+ |
Xiaomi Mi Note 10 Lite | 9.0+ |
Xiaomi Redmi Note 9S | 9.0+ |
Xiaomi Redmi Note 9 Pro | 9.0+ |
Xiaomi Redmi Note 8T | 9.0+ |
Xiaomi Redmi Note 8 | 9.0+ |
Xiaomi Redmi K30 Pro | 9.0+ |
Xiaomi Redmi K20 Pro | 9.0+ |
Xiaomi Redmi K20 | 9.0+ |
Xiaomi Redmi Note 5 Pro | 9.0+ |
Xiaomi Mi CC9 Pro | 9.0+ |
LG G8X ThinQ | 9.0+ |
LG V50S ThinQ | 9.0+ |
LG V60 ThinQ | 9.0+ |
LG V30 | 9.0+ |
Samsung Galaxy Note 10+ 5G | 9.0+ |
Samsung Galaxy S20+ 5G | 9.0+ |
Samsung Galaxy S20+ | 9.0+ |
Samsung Galaxy S20 5G | 9.0+ |
Samsung Galaxy S20 Ultra 5G | 9.0+ |
Samsung Galaxy S20 | 9.0+ |
Samsung Galaxy Note 10+ | 9.0+ |
Samsung Galaxy Note 10 5G | 9.0+ |
Samsung Galaxy Note 10 | 9.0+ |
Samsung A9 Pro | 9.0+ |
Google Pixel 4 XL | 9.0+ |
Google Pixel 4 | 9.0+ |
Google Pixel 4a | 9.0+ |
Google Pixel 3 XL | 9.0+ |
Google Pixel 3 | 9.0+ |
Google Pixel 3a XL | 9.0+ |
Google Pixel 3a | 9.0+ |
Google Pixel 2 XL | 9.0+ |
Google Pixel 2 | 9.0+ |
Google Pixel 1 XL | 9.0+ |
Google Pixel 1 | 9.0+ |
Poco X2 | 9.0+ |
Sharp Aquos R3 SH-04L | 9.0+ |
Geräte für Einzelhandel, Lagerhäuser und Vertriebszentren
Hersteller und Modell | Android-Version |
---|---|
Zebra PS20 | 10.0 und höher |
Zebra TC52/TC52HC | 10.0 und höher |
Zebra TC57 | 10.0 und höher |
Zebra TC72 | 10,0 und höher |
Zebra TC77 | 10.0 und höher |
Zebra MC93 | 10.0 und höher |
Zebra TC8300 | 10.0 und höher |
Zebra VC8300 | 10.0 und höher |
Zebra EC30 | 10.0 und höher |
Zebra ET51 | 10,0 und höher |
Zebra ET56 | 10.0 und höher |
Zebra L10 | 10.0 und höher |
Zebra CC600/CC6000 | 10,0 und höher |
Zebra MC3300x | 10.0 und höher |
Zebra MC330x | 10.0 und höher |
Zebra TC52x | 10.0 und höher |
Zebra TC57x | 10.0 und höher |
Zebra EC50 (LAN und HC) | 10.0 und höher |
Zebra EC55 (WAN) | 10.0 und höher |
WT6300 | 10.0 und höher |
Skorpio X5 | 10.0 und höher |