WLAN-Standort: Entfernung mit RTT

Mit der von der Wi-Fi RTT (Round-Trip-Time) API bereitgestellten WLAN-Standortfunktion können Sie die Entfernung zu WLAN-Zugangspunkten und Wi-Fi Aware-Geräten in der Nähe messen, die RTT unterstützen.

Wenn Sie die Entfernung zu mindestens drei Zugriffspunkten messen, können Sie mit einem Multilaterationsalgorithmus 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 standortbezogene Dienste entwickeln, z. B. Indoor-Navigation, eindeutige Sprachsteuerung (z. B. „Schalte dieses Licht ein“) und standortbezogene Informationen (z. B. „Gibt es Sonderangebote für dieses Produkt?“).

Das anfragende Gerät muss keine Verbindung zu den Zugangspunkten herstellen, um die Entfernung mit Wi‑Fi RTT zu messen. Aus Datenschutzgründen kann nur das anfragende Gerät die Entfernung zum Zugriffspunkt ermitteln. Die Zugriffspunkte haben diese Informationen nicht. Wi‑Fi RTT-Vorgänge sind für Vordergrund-Apps unbegrenzt, werden aber für Hintergrund-Apps gedrosselt.

Wi‑Fi RTT und die zugehörigen Fine-Time-Measurement-Funktionen (FTM) werden im IEEE 802.11-2016-Standard beschrieben. Für Wi‑Fi RTT ist die genaue Zeitmessung erforderlich, die durch FTM bereitgestellt wird, da die Entfernung zwischen zwei Geräten berechnet wird, indem die Zeit gemessen wird, die ein Paket für einen Roundtrip 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 IEEE 802.11az-Entfernungsmessung ohne Trigger (Non-Trigger Based, NTB) eingeführt.

Implementierungsunterschiede je nach Android-Version

Wi‑Fi 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 Daten zu den Standorten von vorab festgelegten Zugangspunkten (Access Points, APs) in Ihrer App. Es liegt an Ihnen, wie Sie diese Daten speichern und abrufen.

Auf Geräten mit Android 10 (API-Level 29) und höher können AP-Standortdaten als ResponderLocation-Objekte dargestellt werden, die Breiten-, Längen- und Höhenkoordinaten enthalten. Bei Wi‑Fi RTT-APs, die LCI/LCR-Daten (Location Configuration Information/Location Civic Report) unterstützen, gibt das Protokoll während des Entfernungsmessungsprozesses ein ResponderLocation-Objekt zurück.

Mit dieser Funktion können Apps direkt bei Zugriffspunkten nach ihrer Position fragen, anstatt diese Informationen vorab speichern zu müssen. Ihre App kann also WLAN-APs finden und ihre Positionen bestimmen, auch wenn die WLAN-APs zuvor nicht bekannt waren, z. B. wenn ein Nutzer ein neues Gebäude betritt.

Die Unterstützung für die IEEE 802.11az-NTB-Entfernungsmessung 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 (gekennzeichnet durch WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_NTB_INITIATOR), kann Ihre App mit einer einzigen Bereichsanfrage sowohl IEEE 802.11mc- als auch IEEE 802.11az-fähige APs finden. Die RangingResult API wurde erweitert, um Informationen zum Mindest- und Höchstwert für das Intervall zwischen Reichweitenmessungen bereitzustellen. Das genaue Intervall wird von Ihrer App gesteuert.

Voraussetzungen

  • Die Hardware des Geräts, das die Entfernungsanfrage stellt, muss den FTM-Standard 802.11-2016 oder den Standard 802.11az (nicht triggerbasierte Entfernungsmessung) implementieren.
  • Auf dem Gerät, das die Entfernungsanfrage stellt, muss Android 9 (API-Level 28) oder höher ausgeführt werden. Die nicht triggerbasierte Entfernungsmessung gemäß IEEE 802.11az ist auf Geräten mit Android 15 (API‑Level 35) und höher aktiviert.
  • Auf dem Gerät, das die Bereichsanfrage stellt, müssen die Standortdienste aktiviert und die WLAN-Suche aktiviert sein (unter Einstellungen > Standort).
  • Wenn die App, die die Bereichsanfrage stellt, 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 Version von Android ausgerichtet ist, muss sie stattdessen die Berechtigung ACCESS_FINE_LOCATION haben.
  • Die App muss den Bereich der Zugriffspunkte abfragen, während die App sichtbar ist oder in einem Dienst im Vordergrund ausgeführt wird. Die App kann nicht im Hintergrund auf Standortinformationen zugreifen.
  • Der Zugriffspunkt muss den IEEE 802.11-2016-FTM-Standard oder den IEEE 802.11az-Standard (nicht triggerbasiertes Ranging) implementieren.

Einrichten

So richten Sie Ihre App für die Verwendung von Wi‑Fi 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 zur Laufzeit jedes Mal anfordern, wenn der Nutzer einen RTT-Scanvorgang ausführen möchte. Ihre App muss die Einwilligung des Nutzers einholen, wenn die Berechtigung noch nicht erteilt wurde. Weitere Informationen zu Laufzeitberechtigungen finden Sie unter App-Berechtigungen anfordern.

2. Prüfen, ob das Gerät Wi‑Fi RTT unterstützt

Wenn Sie prüfen möchten, ob das Gerät Wi‑Fi RTT unterstützt, verwenden Sie die PackageManager API:

Kotlin

context.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)

Java

context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);

3. Prüfen, ob Wi‑Fi RTT verfügbar ist

Wi‑Fi RTT ist möglicherweise auf dem Gerät vorhanden, aber nicht verfügbar, weil der Nutzer WLAN deaktiviert hat. Je nach Hardware und Firmware unterstützen einige Geräte Wi‑Fi RTT möglicherweise nicht, wenn SoftAP oder Tethering verwendet werden. Mit isAvailable() können Sie prüfen, ob Wi‑Fi RTT verfügbar ist.

Die Verfügbarkeit von Wi‑Fi 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 den Broadcast-Intent 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 Broadcasts.

Bereichsanfrage erstellen

Eine Entfernungsanfrage (RangingRequest) wird erstellt, indem eine Liste von APs oder Wi-Fi Aware-Peers angegeben wird, für die eine Entfernung 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 Zugriffspunkt angegeben werden, für den 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 Zugriffspunkt wird durch sein ScanResult-Objekt identifiziert, das durch Aufrufen von WifiManager.getScanResults() abgerufen werden kann. Sie können addAccessPoints(List<ScanResult>) verwenden, um mehrere Zugriffspunkte in einem Batch hinzuzufügen.

ScanResult-Objekte können sowohl IEEE 802.11mc- (is80211mcResponder()) als auch IEEE 802.11az-APs (is80211azNtbResponder()) enthalten, die nicht auf Triggern basieren. Geräte, die IEEE 802.11az-NTB-Ranging unterstützen, führen je nach AP-Funktion entweder 802.11mc- oder 802.11az-Ranging durch. Wenn der AP beide unterstützt, wird standardmäßig 802.11az verwendet. Geräte, die IEEE 802.11az nicht unterstützen, führen alle Entfernungsbestimmungen mit dem IEEE 802.11mc-Protokoll durch.

Ebenso kann mit einer Entfernungsanfrage ein Wi-Fi Aware-Peer entweder über seine MAC-Adresse oder über seine PeerHandle hinzugefügt werden. Verwenden Sie dazu die Methoden addWifiAwarePeer(MacAddress peer) und addWifiAwarePeer(PeerHandle peer). Weitere Informationen zum Erkennen von Wi-Fi Aware-Peers finden Sie in der Wi-Fi Aware-Dokumentation.

Bereichsanfrage

Eine App stellt eine Entfernungsanfrage mit der Methode WifiRttManager.startRanging() und gibt Folgendes an: ein RangingRequest zur Angabe des Vorgangs, ein Executor zur Angabe des Callback-Kontexts und ein RangingResultCallback zum Empfangen der Ergebnisse.

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 Bereichsvorgang wird asynchron ausgeführt und die Bereichsergebnisse werden in einem der Callbacks von RangingResultCallback zurückgegeben:

  • Wenn der gesamte Bereichsvorgang fehlschlägt, wird der onRangingFailure-Callback mit einem Statuscode ausgelöst, der in RangingResultCallback beschrieben wird. Ein solcher Fehler kann auftreten, wenn der Dienst zu diesem Zeitpunkt keinen Bereichsvorgang ausführen kann, z. B. weil WLAN deaktiviert ist, weil die Anwendung zu viele Bereichsvorgänge angefordert hat und gedrosselt wird oder weil ein Berechtigungsproblem vorliegt.
  • Wenn der Bereichsvorgang 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 entspricht nicht unbedingt der Reihenfolge der Anfragen. Der Bereichsvorgang kann abgeschlossen werden, aber jedes Ergebnis kann trotzdem auf einen Fehler bei der jeweiligen Messung hinweisen.

Ergebnisse der Bereichsanalyse interpretieren

Jedes der Ergebnisse, die vom onRangingResults-Callback zurückgegeben werden, wird durch ein RangingResult-Objekt angegeben. Führen Sie bei jeder Anfrage die folgenden Schritte aus.

1. Anfrage identifizieren

Identifizieren Sie die Anfrage anhand der Informationen, die beim Erstellen des RangingRequest angegeben wurden. Meistens ist das eine MAC-Adresse, die im ScanResult angegeben ist und einen Zugriffspunkt identifiziert. Die MAC-Adresse kann mit der Methode getMacAddress() aus dem Bereichsergebnis abgerufen werden.

Die Liste der Entfernungsergebnisse kann in einer anderen Reihenfolge als die in der Entfernungsmessungsanfrage angegebenen Peers (Zugriffspunkte) vorliegen. Verwenden Sie daher die MAC‑Adresse, um den Peer zu identifizieren, nicht die Reihenfolge der Ergebnisse.

2. Ermitteln, ob jede 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 Anforderungs-ID) 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 Ergebniswerte mit den entsprechenden get-Methoden abrufen:

  • Entfernung in Millimetern und Standardabweichung der Messung:

    getDistanceMm()

    getDistanceStdDevMm()

  • RSSI der für die Messungen verwendeten Pakete:

    getRssi()

  • Zeit in Millisekunden, zu der die Messung durchgeführt wurde (gibt die Zeit seit dem Booten an):

    getRangingTimestampMillis()

  • Anzahl der Messungen, die versucht wurden, und Anzahl der Messungen, die erfolgreich waren (und auf denen die Entfernungsmessungen basieren):

    getNumAttemptedMeasurements()

    getNumSuccessfulMeasurements()

  • Mindest- und Höchstzeit, die ein Clientgerät zwischen 11az-NTB-Messungen warten muss:

    getMinTimeBetweenNtbMeasurementsMicros() und getMaxTimeBetweenNtbMeasurementsMicros() geben die Mindest- und Höchstzeit zurück. Wenn die nächste Entfernungsmessung angefordert wird, bevor die Mindestzeit abgelaufen ist, gibt die API das im Cache gespeicherte Entfernungsergebnis zurück. Wenn die nächste Entfernungsmessung nach Ablauf der maximalen Zeit angefordert wird, beendet die API die nicht triggerbasierte Entfernungsmessung und handelt eine neue Entfernungsmessung mit der antwortenden Station aus. Sie sollten keine neue Ranging-Sitzung anfordern, da dies die Ranging-Messzeit verlängert. Um die Effizienz der nicht triggerbasierten Entfernungsmessung gemäß 802.11az optimal zu nutzen, lösen Sie die nächste Entfernungsmessungsanfrage zwischen der minimalen und maximalen Messzeit aus, die in der vorherigen RangingResult-Messung angegeben ist.

  • Wiederholungen des Long Training Field (LTF), die Responder- und Initiatorstationen in der Präambel für das IEEE 802.11az-NTB-Ergebnis verwendet haben:

    get80211azResponderTxLtfRepetitionsCount()

    get80211azInitiatorTxLtfRepetitionsCount()

  • Anzahl der räumlichen Zeitstreams (Spatial Time Streams, STS) für die Übertragung und den Empfang, die die Initiatorstation für das IEEE 802.11az-NTB-Ergebnis verwendet hat:

    get80211azNumberOfTxSpatialStreams()

    get80211azNumberOfRxSpatialStreams()

Android-Geräte, die WiFi-RTT unterstützen

In den folgenden Tabellen sind einige Smartphones, Zugangspunkte und Geräte für Einzelhandel, Lagerhaltung und Vertriebszentren aufgeführt, die WiFi-RTT unterstützen. Diese sind bei Weitem nicht vollständig. Wenn Sie Ihre RTT-fähigen Produkte hier auflisten möchten, wenden Sie sich bitte an uns.

Zugangspunkte

Hersteller und Modell Supportdatum Protokoll
Nest Wifi Pro (Wi-Fi 6E) Unterstützt mc
Compulab WILD AP Unterstützt mc
Google Wifi Unterstützt mc
Google Nest Wifi-Router Unterstützt mc
Google Nest Wifi-Zugangspunkt Unterstützt mc
Aruba AP-635 Unterstützt mc
Cisco 9130 Unterstützt mc
Cisco 9136 Unterstützt mc
Cisco 9166 Unterstützt mc
Cisco 9164 Unterstützt mc
Cisco CW9172I Unterstützt mc/az
Cisco CW9172H Unterstützt mc/az
Cisco CW9176I Unterstützt mc/az
Cisco CW9178I Unterstützt mc/az
Aruba AP-505 Unterstützt mc
Aruba AP-515 Unterstützt mc
Aruba AP-575 Unterstützt mc
Aruba AP-518 Unterstützt mc
Aruba AP-505H Unterstützt mc
Aruba AP-565 Unterstützt mc
Aruba AP-535 Unterstützt mc
Aruba AP567 Unterstützt mc
Aruba AP577 Unterstützt mc
Aruba AP555 Unterstützt mc
Aruba AP635 Unterstützt mc
Aruba AP655 Unterstützt mc
Aruba AP615 Unterstützt mc
Aruba AP734 Unterstützt mc/az
Aruba AP735 Unterstützt mc/az
Aruba AP754 Unterstützt mc/az
Aruba AP755 Unterstützt mc/az

Smartphones

Hersteller und Modell Android-Version
Google Pixel 9 Pro XL 14+
Google Pixel 9 14+
Google Pixel 9 Pro 14+
Google Pixel 9 Pro XL 14+
Google Pixel 7a 14+
Google Pixel 7 14+
Google Pixel 8 14+
Google Pixel 8 Pro 14+
Google Pixel 8a 14+
Samsung SM-S918B 14+
Samsung SM-A515F 14+
Google Pixel 9 Pro 14+
Samsung SM-A546E 14+
Samsung SM-S928B 14+
Samsung SM-A217F 14+
Samsung SM-A715F 14+
Samsung SM-A528B 14+
Samsung SM-A135F 14+
Samsung SM-S911B 14+
Xiaomi 21091116AI 14+
Google Pixel 9 14+
Samsung SM-A127F 14+
Google Pixel 7 Pro 14+
Samsung SM-A556E 14+
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, Lagerung und Vertriebszentren

Hersteller und Modell Android-Version
Zebra PS20 10.0+
Zebra TC52/TC52HC 10.0+
Zebra TC57 10.0+
Zebra TC72 10.0+
Zebra TC77 10.0+
Zebra MC93 10.0+
Zebra TC8300 10.0+
Zebra VC8300 10.0+
Zebra EC30 10.0+
Zebra ET51 10.0+
Zebra ET56 10.0+
Zebra L10 10.0+
Zebra CC600/CC6000 10.0+
Zebra MC3300x 10.0+
Zebra MC330x 10.0+
Zebra TC52x 10.0+
Zebra TC57x 10.0+
Zebra EC50 (LAN und HC) 10.0+
Zebra EC55 (WAN) 10.0+
Zebra WT6300 10.0+
Skorpio X5 10.0+