Możesz używać funkcji lokalizacji przez Wi-Fi udostępnianej przez interfejs API Wi-Fi RTT (Round-Trip-Time) do pomiaru odległości do pobliskich punktów dostępowych Wi-Fi obsługujących RTT i urządzeń Wi-Fi Aware.
Jeśli zmierzono odległość do co najmniej 3 punktów dostępu, możesz użyć algorytmu wielobocznego, aby oszacować pozycję urządzenia, która najlepiej pasuje do tych pomiarów. Wynik jest zwykle dokładny do 1–2 metrów.
Taka dokładność pozwala na tworzenie szczegółowych usług wykorzystujących lokalizację, takich jak jako nawigacji wewnątrz budynków, szczegółowe sterowanie głosem (na przykład „Włącz to „światła”) i informacji opartych na lokalizacji (np. „Czy są dostępne danego produktu?”).
Urządzenie wysyłające żądanie nie musi łączyć się z punktami dostępu, aby przeprowadzać pomiary w odległości za pomocą RTT Wi-Fi. Ze względu na ochronę prywatności tylko urządzenie wysyłające żądanie może określić odległość do punktu dostępu. Punkty dostępu nie mają dostępu do tych informacji. Operacje RTT Wi-Fi nie są ograniczone w przypadku aplikacji działających na pierwszym planie, ale ograniczona dla aplikacji działających w tle.
RTT Wi-Fi i powiązane funkcje dokładnego pomiaru czasu (FTM) są standardem IEEE 802.11-2016. RTT w Wi-Fi wymaga dokładnej godziny pomiar dostarczony przez FTM, ponieważ oblicza odległość między dwoma urządzeń, mierząc czas potrzebny pakietowi na pokonanie tych urządzeń i mnożąc ten czas przez prędkość światła.
W Androidzie 15 (poziom API 35) wprowadzono obsługę pomiaru odległości (NTB) w standardzie IEEE 802.11az.
Różnice we wdrożeniu w zależności od wersji Androida
Protokół Wi-Fi RTT został wprowadzony w Androidzie 9 (poziom interfejsu API 28). W przypadku korzystania z tego protokołu do określania pozycji urządzenia za pomocą wieloopóźnienia przy włączonym urządzeniu Android 9: potrzebujesz dostępu do wcześniej określonych lokalizacji punktów dostępu. w Twojej aplikacji. To Ty decydujesz, jak chcesz przechowywać i odzyskać te dane.
Na urządzeniach z Androidem 10 (poziom interfejsu API 29) lub nowszym dane o lokalizacji punktu dostępu
reprezentowane jako
ResponderLocation
takich jak szerokość, długość i wysokość nad poziomem morza. W przypadku punktów dostępowych Wi-Fi RTT, które obsługują informacje o konfiguracji lokalizacji lub raporty o lokalizacji (dane LCI/LCR), protokół zwróci obiekt ResponderLocation
podczas procesu pomiaru zasięgu.
Ta funkcja pozwala aplikacjom wysyłać zapytania do punktów dostępu, aby bezpośrednio prosić ich o podanie pozycji bez konieczności zapisywania tych informacji z wyprzedzeniem. Dzięki temu Twoja aplikacja może znajdować punkty dostępu i określać ich pozycje, nawet jeśli nie były one wcześniej znane, na przykład gdy użytkownik wchodzi do nowego budynku.
Obsługa pomiaru zasięgu NTB w standardzie IEEE 802.11az jest dostępna na urządzeniach z Androidem 15 (poziom API 35) lub nowszym. Oznacza to, że jeśli urządzenie obsługuje tryb odpowiedzi IEEE 802.11az NTB (wskazany przez WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_STA_RESPONDER
), aplikacja może znaleźć punkty dostępu obsługujące zarówno IEEE 802.11mc, jak i IEEE 802.11az za pomocą pojedynczego żądania zakresu. Rozszerzyliśmy interfejs API RangingResult
, aby dostarczać informacje
o minimalnej i maksymalnej wartości, jaka może być używana w przedziale między
wybierając zakres pomiarów, pozostawiając dokładny odstęp czasu w aplikacji.
Wymagania
- Sprzęt urządzenia wysyłającego żądanie pomiaru zasięgu musi być zgodny ze standardem FTM 802.11-2016 lub standardem 802.11az (pomiar zasięgu bez wyzwalacza).
- Urządzenie przesyłające żądanie określania zakresu musi mieć Androida 9 (poziom interfejsu API) 28) lub nowsze. Na urządzeniach z Androidem 15 (poziom interfejsu API 35) lub nowszym włączone jest określanie odległości za pomocą standardu IEEE 802.11az bez wyzwalacza.
- Urządzenie przesyłające żądanie określania zakresu musi mieć włączone usługi lokalizacyjne i włączone skanowanie Wi-Fi (w sekcji Ustawienia > Lokalizacja).
- Jeśli aplikacja wysyłająca żądanie określania zakresu jest kierowana
Androida 13 (poziom API 33) lub nowszego, musi mieć
NEARBY_WIFI_DEVICES
uprawnienia. Jeśli taka aplikacja jest przeznaczona na wcześniejszą wersję Androida, musi mieć uprawnienieACCESS_FINE_LOCATION
. - Aplikacja musi wysyłać zapytania dotyczące zakresu punktów dostępu, gdy aplikacja jest widoczna lub w nie działa na pierwszym planie. Aplikacja nie może uzyskiwać dostępu do informacji o lokalizacji w tle.
- Punkt dostępu musi implementować standard IEEE 802.11-2016 FTM lub IEEE Standard 802.11az (zakres bez reguł).
Konfiguracja
Aby skonfigurować aplikację do korzystania z RTT Wi-Fi, wykonaj te czynności.
1. Poproś o uprawnienia
W pliku manifestu aplikacji poproś o te uprawnienia:
<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" />
Uprawnienia NEARBY_WIFI_DEVICES
i ACCESS_FINE_LOCATION
są niebezpieczne
uprawnień, więc musisz o nie prosić za każdym razem, gdy użytkownik chce
i wykonać operację skanowania RTT. Jeśli użytkownik nie przyznał jeszcze uprawnień, aplikacja będzie musiała o nie poprosić. Więcej informacji
o uprawnieniach czasu działania, zobacz
Poproś o uprawnienia aplikacji.
2. Sprawdź, czy urządzenie obsługuje Wi-Fi RTT
Aby sprawdzić, czy urządzenie obsługuje RTT w sieci Wi-Fi, użyj
Interfejs API PackageManager
:
Kotlin
context.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)
Java
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);
3. Sprawdzanie, czy dostępna jest funkcja RTT Wi-Fi
Funkcja RTT Wi-Fi może być dostępna na urządzeniu, ale może być wyłączona, ponieważ użytkownik wyłączył Wi-Fi. W zależności od możliwości sprzętowych i oprogramowania niektóre urządzenia mogą nie obsługiwać RTT Wi-Fi, jeśli są używane w nich funkcje SoftAP lub tetheringu. Aby sprawdzić
czy dostępna jest opcja RTT Wi-Fi,
isAvailable()
Dostępność Wi-Fi RTT może się zmienić w dowolnym momencie. Aplikacja powinna zarejestrować
BroadcastReceiver
aby otrzymać
ACTION_WIFI_RTT_STATE_CHANGED
,
który jest wysyłany, gdy dostępność się zmieni. Kiedy aplikacja odbiera transmisję
aplikacja powinna sprawdzić bieżący stan dostępności i dostosować
odpowiednie zachowanie.
Na przykład:
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);
Więcej informacji znajdziesz w artykule Transmisje.
Tworzenie żądania pomiaru zasięgu
Prośba o określenie zakresu
Utworzono (RangingRequest
)
przez określenie listy punktów dostępu lub elementów równorzędnych z modułem Wi-Fi Aware, do których
jest żądane. W elemencie
żądanie pojedynczego zakresu; odległość od wszystkich urządzeń jest mierzona i zwracana.
Na przykład żądanie może używać metody addAccessPoint()
, aby określić punkt dostępu, dla którego ma być zmierzona odległość:
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();
Punkt dostępu jest identyfikowany przez
ScanResult
, którym może być
uzyskanych dzięki wywołaniu
WifiManager.getScanResults()
Możesz użyć addAccessPoints(List<ScanResult>)
, aby dodać wiele punktów dostępu w grupie.
Obiekty ScanResult
mogą zawierać punkty dostępowe obsługujące standard IEEE 802.11mc (is80211mcResponder()
) i standard IEEE 802.11az (is80211azNtbResponder()
) z obsługą pomiarów bez wyzwalania. Urządzenia, które obsługują pomiar zasięgu NTB w standardzie IEEE 802.11az, wykonują pomiar zasięgu w standardzie 802.11mc lub 802.11az w zależności od możliwości punktu dostępu. Domyślnie jest używany standard 802.11az, jeśli punkt dostępu obsługuje oba standardy. Urządzenia, które nie obsługują IEEE 802.11az, mają wszystkie
wykorzystując protokół IEEE 802.11mc.
Podobnie żądanie pomiaru zasięgu może dodać urządzenie obsługujące Wi-Fi Aware, używając jego adresu MAC lub PeerHandle
, odpowiednio za pomocą metod addWifiAwarePeer(MacAddress peer)
i addWifiAwarePeer(PeerHandle peer)
. Więcej informacji o wykrywaniu urządzeń Wi-Fi Aware znajdziesz w dokumentacji Wi-Fi Aware.
Zakres żądań
Aplikacja wysyła żądanie pomiaru za pomocą metody WifiRttManager.startRanging()
, podając: RangingRequest
, aby określić operację, Executor
, aby określić kontekst wywołania zwrotnego, oraz RangingResultCallback
, aby otrzymać wyniki.
Na przykład:
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) { … } });
Operacja określania zakresu jest wykonywana asynchronicznie, a zakres wyników jest
zwracany w jednym z wywołań zwrotnych
RangingResultCallback
:
- Jeśli operacja określania zakresu zakończy się niepowodzeniem, funkcja
onRangingFailure
wywołanie zwrotne jest wywoływane z kodem stanu opisanym wRangingResultCallback
Taki błąd może wystąpić, jeśli usługa nie może wykonać operacji pomiaru odległości w danym momencie – na przykład dlatego, że Wi-Fi jest wyłączone, aplikacja poprosiła o zbyt wiele operacji pomiaru odległości i została ograniczona lub z powodu problemu z uprawnieniami. - Po zakończeniu operacji określania zakresu funkcja
onRangingResults
wywołanie zwrotne z listą wyników pasujących do listy żądań – jeden wynik na każde żądanie. Kolejność wyników nie jest muszą się zgadzać z kolejnością żądań. Pamiętaj, że operacja określania zakresu może ale każdy wynik może wskazywać na niepowodzenie danego pomiar skuteczności.
Interpretowanie wyników pomiaru zasięgu
Każdy z wyników zwracanych przez funkcję wywołania zwrotnego onRangingResults
jest określony przez obiekt RangingResult
. Wykonaj te czynności przy każdym żądaniu.
1. Zidentyfikuj żądanie
zidentyfikować prośbę na podstawie informacji podanych podczas tworzenia RangingRequest
: najczęściej jest to adres MAC podany w ScanResult
, który identyfikuje punkt dostępu; Adres MAC można uzyskać z wyniku określania zakresu za pomocą funkcji
getMacAddress()
.
Lista wyników z przedziałem może mieć inną kolejność niż wyniki z grupy porównawczej (dostęp punktów) określonych w prośbie o zakres zakresu, więc należy użyć adresu MAC, identyfikować elementy porównawcze, a nie kolejność wyników.
2. Określanie, czy poszczególne pomiary zakończyły się powodzeniem
Aby sprawdzić, czy pomiar był udany, skorzystaj z
getStatus()
. Wartość inna niż STATUS_SUCCESS
oznacza błąd. Błąd oznacza, że wszystkie pozostałe pola tego wyniku
(z wyjątkiem powyższego identyfikatora żądania) są nieprawidłowe i odpowiadają im odpowiednie wartości
Metoda get*
zakończy się niepowodzeniem z
Wyjątek: IllegalStateException
.
3. Pobieranie wyników każdego udanego pomiaru
W przypadku każdego udanego pomiaru (RangingResult
) możesz pobrać wyniki
odpowiednimi metodami get
:
Odległość w mm i odchylenie standardowe pomiaru:
RSSI pakietów używanych na potrzeby pomiarów:
Czas w milisekundach, w którym dokonano pomiaru (czas od momentu uruchomienia):
Liczba prób pomiarów i liczba pomiarów, które zakończyły się powodzeniem (i na których opierają się pomiary odległości):
Minimalny i maksymalny czas oczekiwania urządzenia klienckiego w zakresie 11 az NTB pomiary:
getMinTimeBetweenNtbMeasurementsMicros()
orazgetMaxTimeBetweenNtbMeasurementsMicros()
zwracają minimalny i maksymalny czas. Jeśli następny pomiar zakresu to żądania przed upłynięciem minimalnego czasu, interfejs API zwraca wyniku zakresu w pamięci podręcznej. Jeśli zażądany zostanie kolejny pomiar zakresu po po upływie maksymalnego czasu, interfejs API kończy działanie niebędące wyzwalaczem. dobiera zakres sesji i negocjuje nową sesję określania zakresu z odpowiedzialną . Unikaj prośby o nową sesję z zakresem, ponieważ spowoduje to dodanie co przekłada się na dłuższy czas pomiaru. Aby w pełni wykorzystać wydajność pomiaru zasięgu w standardzie 802.11az bez korzystania z wyzwalania, wywołaj kolejne żądanie pomiaru zasięgu w okresie między minimalnym a maksymalnym czasem pomiaru określonym w poprzednim pomiarzeRangingResult
.Powtórzenia długiego pola treningowego (LTF), które stacje odpowiadające i inicjujące używają w preambule w przypadku wyniku IEEE 802.11az NTB:
Liczba strumieni czasowych przestrzennych (STS) do przesyłania i odbierania, których używa inicjator stacji do wyniku NTB IEEE 802.11az:
Urządzenia z Androidem obsługujące Wi-Fi-RTT
W tabelach poniżej znajdziesz listę niektórych telefonów, punktów dostępu i urządzeń do sprzedaży detalicznej, magazynowania i centrum dystrybucji, które obsługują WiFi-RTT. Nie są one w żaden sposób wyczerpujące. Zachęcamy do skontaktuj się z nami , aby wyświetlić produkty obsługujące RTT.
Punkty dostępu
Producent i model | Data wsparcia |
---|---|
Nest Wifi Pro (Wi-Fi 6E) | Obsługiwane |
Przeprowadź obliczenia WILD AP | Obsługiwane |
Google Wi-Fi | Obsługiwane |
router Wi-Fi Google Nest | Obsługiwane |
Punkt Google Nest Wi-Fi | Obsługiwane |
Aruba AP-635 | Obsługiwane |
Cisco 9130 | Obsługiwane |
Cisco 9136 | Obsługiwane |
Cisco 9166 | Obsługiwane |
Cisco 9164 | Obsługiwane |
Aruba AP-505 | Obsługiwane |
Aruba AP-515 | Obsługiwane |
Aruba AP-575 | Obsługiwane |
Aruba AP-518 | Obsługiwane |
Aruba AP-505H | Obsługiwane |
Aruba AP-565 | Obsługiwane |
Aruba AP-535 | Obsługiwane |
Telefony
Producent i model | Wersja Androida |
---|---|
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 lub nowszy | 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+ |
Urządzenia do sklepów, magazynów i centrów dystrybucyjnych
Producent i model | Wersja Androida |
---|---|
Zebra PS20 | 10.0 lub nowszy |
Zebra TC52/TC52HC | 10.0 lub nowszy |
Zebra TC57 | 10.0 lub nowszy |
Zebra TC72 | 10.0 lub nowszy |
Zebra TC77 | 10,0+ |
Zebra MC93 | 10.0 lub nowszy |
Zebra TC8300 | 10.0 lub nowszy |
Zebra VC8300 | 10,0+ |
Zebra EC30 | 10,0+ |
Zebra ET51 | 10,0+ |
Zebra ET56 | 10.0 lub nowszy |
Zebra L10 | 10.0 lub nowszy |
Zebra CC600/CC6000 | 10,0+ |
Zebra MC3300x | 10,0+ |
Zebra MC330x | 10,0+ |
Zebra TC52x | 10,0+ |
Zebra TC57x | 10.0 lub nowszy |
Zebra EC50 (LAN i HC) | 10.0 lub nowszy |
Zebra EC55 (WAN) | 10,0+ |
Zebra WT6300 | 10,0+ |
Skorpio X5 | 10.0 lub nowszy |