Puoi utilizzare la funzionalità di geolocalizzazione della rete Wi-Fi fornita API Wi-Fi RTT (Round-Trip-Time) per misurare la distanza da punti di accesso Wi-Fi compatibili con RTT nelle vicinanze e peer Dispositivi Wi-Fi Aware.
Se misuri la distanza da tre o più punti di accesso, puoi utilizzare un algoritmo multilaterale per stimare la posizione del dispositivo più adatta a quelle le misurazioni. In genere il risultato è preciso entro 1-2 metri.
Con questa precisione, puoi sviluppare servizi granulari basati sulla posizione geografica, come come navigazione interna, controllo vocale con ambiguità (ad esempio, "Attiva luce") e informazioni basate sulla località (ad esempio, "Ci sono offerte speciali) per questo prodotto?").
Il dispositivo richiedente non deve necessariamente connettersi ai punti di accesso per eseguire la misurazione distanza con RTT Wi-Fi. Per garantire la privacy, solo il dispositivo che ha inviato la richiesta è in grado di per determinare la distanza dal punto di accesso. i punti di accesso non hanno queste informazioni. Le operazioni RTT Wi-Fi sono illimitate per le app in primo piano, ma limitata per le app in background.
La tecnologia RTT Wi-Fi e le relative funzionalità di misurazione fine (FTM) sono specificato dallo standard IEEE 802.11-2016. La funzionalità RTT Wi-Fi richiede l'ora esatta misurazione fornita da FTM perché calcola la distanza tra due misurando il tempo impiegato da un pacchetto per fare un viaggio di andata e ritorno tra e moltiplicando il tempo per la velocità della luce.
Android 15 (livello API 35) ha introdotto il supporto per lo standard IEEE 802.11az non basato su trigger (NTB).
Differenze di implementazione in base alla versione di Android
Il Wi-Fi RTT è stato introdotto in Android 9 (livello API 28). Quando si utilizza questo protocollo per determinare la posizione di un dispositivo utilizzando la multilaterazione con dispositivi in esecuzione Android 9, devi avere accesso a posizioni predeterminate dei punti di accesso (AP) i dati nella tua app. Sei tu a decidere come archiviare e recuperare questi dati.
Sui dispositivi con Android 10 (livello API 29) e versioni successive, i dati sulla posizione AP possono essere
rappresentato come
ResponderLocation
oggetti, tra cui latitudine, longitudine e altitudine. Per gli AP Wi-Fi RTT che
supportare le informazioni sulla configurazione della località/il Report civico sulla posizione (dati LCI/LCR),
il protocollo restituirà un oggetto ResponderLocation
durante
processo variabile.
Questa funzionalità consente alle app di interrogare gli AP per chiedere direttamente la loro posizione anziché doverli archiviare preventivamente. Quindi, la tua app può trovare AP e determinare le loro posizioni anche se questi non erano noti prima, ad esempio quando un utente entra in un nuovo edificio.
Il supporto per lo standard IEEE 802.11az NTB è disponibile sui dispositivi con Android 15
(livello API 35) e superiori. Ciò significa che se il dispositivo supporta lo standard IEEE 802.11az
Modalità risponditore NTB (indicata da
WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_STA_RESPONDER
),
l'app può trovare sia gli AP compatibili con IEEE 802.11mc che IEEE 802.11az con un
di una richiesta di intervallo. L'API RangingResult
è stata estesa per fornire informazioni
sul valore minimo e massimo che può essere utilizzato per l'intervallo
misurazioni, lasciando l'intervallo esatto nel controllo dell'app.
Requisiti
- L'hardware del dispositivo che effettua la richiesta di portata deve implementare il parametro Standard FTM 802.11-2016 o standard 802.11az (intervallo non basato su trigger).
- Sul dispositivo che effettua la richiesta di portata deve essere installato Android 9 (livello API) 28) o versioni successive. Il raggio d'azione non basato su trigger IEEE 802.11az è abilitato sui dispositivi con Android 15 (livello API 35) e versioni successive.
- Sul dispositivo che effettua la richiesta di rilevamento devono essere abilitati i servizi di geolocalizzazione e ricerca di reti Wi-Fi attivata (in Impostazioni > Posizione).
- Se l'app che effettua le richieste di portata target
Android 13 (livello API 33) o versioni successive, deve avere il
NEARBY_WIFI_DEVICES
autorizzazione. Se un'app di questo tipo ha come target una versione precedente di Android, deve avereACCESS_FINE_LOCATION
l'autorizzazione di accesso. - L'app deve eseguire query sull'intervallo di punti di accesso mentre è visibile o in un servizio in primo piano. L'app non può accedere alle informazioni sulla posizione da lo sfondo.
- Il punto di accesso deve implementare lo standard FTM IEEE 802.11-2016 o IEEE Standard 802.11az (intervallo non basato su trigger).
Configura
Per configurare l'app per l'utilizzo di Wi-Fi RTT, svolgi i passaggi che seguono.
1. Richiedi autorizzazioni
Richiedi le seguenti autorizzazioni nel file manifest dell'app:
<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" />
Le autorizzazioni NEARBY_WIFI_DEVICES
e ACCESS_FINE_LOCATION
sono pericolose
autorizzazioni, quindi devi richiederle in fase di runtime ogni volta che l'utente vuole
eseguire un'operazione di scansione RTT. La tua app dovrà richiedere all'utente
se l'autorizzazione non è già stata concessa. Per ulteriori informazioni
sulle autorizzazioni di runtime, consulta
Richiedi autorizzazioni app.
2. Controlla se il dispositivo supporta la funzionalità Wi-Fi RTT
Per verificare se il dispositivo supporta Wi-Fi RTT, utilizza il
API PackageManager
:
Kotlin
context.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)
Java
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);
3. Verificare se la funzionalità RTT Wi-Fi è disponibile
Sul dispositivo potrebbe essere presente la tecnologia RTT Wi-Fi, che però potrebbe non essere disponibile perché l'utente
ha disattivato il Wi-Fi. A seconda delle funzionalità hardware e firmware,
i dispositivi potrebbero non supportare la funzionalità Wi-Fi RTT se sono in uso SoftAP o il tethering. Per verificare
se la funzionalità Wi-Fi RTT è disponibile, chiama
isAvailable()
La disponibilità della funzionalità RTT Wi-Fi può variare in qualsiasi momento. L'app deve registrare un
BroadcastReceiver
per ricevere
ACTION_WIFI_RTT_STATE_CHANGED
,
che viene inviato quando la disponibilità cambia. Quando la tua app riceve la trasmissione
l'intent, l'app deve controllare lo stato di disponibilità attuale e modificarne
comportamento degli utenti.
Ad esempio:
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);
Per ulteriori informazioni, vedi Trasmissioni.
Crea una richiesta con intervallo
Una richiesta vagante
(RangingRequest
) è stata creata
specificando un elenco di punti di accesso o peer Wi-Fi Aware a cui
. È possibile specificare più punti di accesso o peer Wi-Fi Aware in un
una richiesta singola; vengono misurate e restituite le distanze
da tutti i dispositivi.
Ad esempio, una richiesta può utilizzare
addAccessPoint()
per specificare un punto di accesso a cui misurare la distanza:
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();
Un punto di accesso è identificato dal suo
ScanResult
, che può essere
ottenuto chiamando
WifiManager.getScanResults()
.
Puoi utilizzare la modalità
addAccessPoints(List<ScanResult>)
per aggiungere più punti di accesso in un batch.
ScanResult
oggetti possono contenere sia lo standard IEEE 802.11mc (is80211mcResponder()
) che
Intervallo non basato su trigger IEEE 802.11az (is80211azNtbResponder()
) supportato
AP I dispositivi che supportano lo standard IEEE 802.11az NTB funzionano con lo standard 802.11mc o
802.11az che varia a seconda delle capacità dell'AP, per impostazione predefinita su 802.11az quando
l'AP supporta entrambi. I dispositivi che non supportano lo standard IEEE 802.11az eseguono tutte le
che vanno dal protocollo IEEE 802.11mc.
Allo stesso modo, una richiesta di portata può aggiungere un peer Wi-Fi Aware utilizzando il suo MAC
o relativo PeerHandle
, utilizzando
il
addWifiAwarePeer(MacAddress peer)
e addWifiAwarePeer(PeerHandle peer)
rispettivamente. Per ulteriori informazioni sul rilevamento di peer Wi-Fi Aware,
consulta la documentazione di Wi-Fi Aware.
Intervallo di richiesta
Un'app emette una richiesta di portata utilizzando
WifiRttManager.startRanging()
e fornendo quanto segue:
RangingRequest
per specificare
operativa, un Executor
per specificare
il contesto del callback
RangingResultCallback
per ricevere i risultati.
Ad esempio:
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) { … } });
L'operazione di intervallo viene eseguita in modo asincrono e i risultati di intervallo sono
in uno dei callback
RangingResultCallback
:
- Se l'intera operazione di intervallo non riesce,
onRangingFailure
il callback viene attivato con un codice di stato descritto inRangingResultCallback
. Un errore di questo tipo può verificarsi se il servizio non può eseguire un'operazione di intervallo in quel momento, ad esempio perché il Wi-Fi è disattivato, perché l'applicazione ha richiesto troppe operazioni di intervallo ed è limitato oppure a causa di un problema di autorizzazione. - Al termine dell'operazione,
onRangingResults
il callback viene attivato con un elenco di risultati che corrispondono all'elenco di richieste, un risultato per ogni richiesta. L'ordine dei risultati non corrisponde corrispondono necessariamente all'ordine delle richieste. Tieni presente che l'operazione di portata completa, ma ogni risultato potrebbe comunque indicare un errore dello specifico misurazione.
Interpreta i risultati con intervallo
Ciascuno dei risultati restituiti
onRangingResults
è specificato da un RangingResult
. Per ogni richiesta, procedi nel seguente modo.
1. Identifica la richiesta
Identifica la richiesta in base alle informazioni fornite durante la creazione dell'elemento
RangingRequest
:
molto spesso un indirizzo MAC fornito nel ScanResult
che identifica un accesso
punto di accesso. L'indirizzo MAC può essere ottenuto dal risultato di intervallo utilizzando il parametro
getMacAddress()
.
L'elenco dei risultati di intervallo potrebbe essere in un ordine diverso rispetto a quello delle app peer (accesso punti) specificati nella richiesta di portata, quindi dovresti usare l'indirizzo MAC per identificare il peer, non l'ordine dei risultati.
2. Determinare se ogni misurazione è riuscita
Per determinare se una misurazione è riuscita, utilizza la classe
getStatus()
. Qualsiasi valore diverso da
STATUS_SUCCESS
indica un errore. Un errore significa che tutti gli altri campi di questo risultato
(ad eccezione dell'identificazione richiesta di cui sopra) non sono validi e i relativi
Il metodo get*
avrà esito negativo con un
IllegalStateException
.
3. Ottieni risultati per ogni misurazione riuscita
Per ogni misurazione riuscita (RangingResult
), puoi recuperare un risultato
con i rispettivi metodi get
:
Distanza in mm e deviazione standard della misura:
RSSI dei pacchetti utilizzati per le misurazioni:
Tempo in millisecondi in cui è stata effettuata la misurazione (che indica il tempo dall'avvio):
Numero di misurazioni tentate e numero di misurazioni riusciti (e su cui si basano le misurazioni della distanza):
Tempo minimo e massimo di un dispositivo client che deve attendere tra 11 az NTB misure:
getMinTimeBetweenNtbMeasurementsMicros()
egetMaxTimeBetweenNtbMeasurementsMicros()
restituisce il tempo minimo e massimo. Se la misura successiva è richiesto prima che sia trascorso il tempo minimo, l'API restituisce risultato con intervallo memorizzato nella cache. Se viene richiesta la misurazione dell'intervallo successivo dopo trascorso il tempo massimo, l'API termina il non-trigger sessione di intervallo e negozia una nuova sessione di portata con il stazione di noleggio. Dovresti evitare di richiedere una nuova sessione di rilevamento, perché aggiunge dall'overhead al tempo di misurazione della distanza. Per sfruttare al meglio 802.11az efficienza con intervallo non basato su attivatore, attiva la richiesta di intervallo successiva tra il tempo di misurazione minimo e massimo specificato nella precedente Misurazione diRangingResult
.ripetizioni sul campo di addestramento lungo (LTF) che le stazioni di risposta e iniziatore utilizzata nel preambolo per il risultato dello standard IEEE 802.11az NTB:
Numero di flussi di tempo spaziali (STS) di trasmissione e ricezione che l'iniziatore stazione utilizzata per il risultato dello standard IEEE 802.11az NTB:
Dispositivi Android che supportano Wi-Fi-RTT
Le seguenti tabelle elencano alcuni telefoni, punti di accesso e dispositivi per attività di vendita al dettaglio, magazzinaggio e centri di distribuzione. che supportano Wi-Fi-RTT. Sono tutt'altro che esaustivi. Ti invitiamo a contattaci per elencare qui i tuoi prodotti che supportano RTT.
Punti di accesso
Produttore e modello | Data di assistenza |
---|---|
Nest Wifi Pro (Wi-Fi 6E) | Supportato |
Compulab WILD AP | Supportato |
Google Wifi | Supportato |
Router Wi-Fi Google Nest | Supportato |
Punto di accesso Google Nest | Supportato |
Aruba AP-635 | Supportato |
Cisco 9130 | Supportato |
Cisco 9136 | Supportato |
Cisco 9166 | Supportato |
Cisco 9164 | Supportato |
Aruba AP-505 | Supportato |
Aruba AP-515 | Supportato |
Aruba AP-575 | Supportato |
Aruba AP-518 | Supportato |
Aruba AP-505H | Supportato |
Aruba AP-565 | Supportato |
Aruba AP-535 | Supportato |
Smartphone
Produttore e modello | Versione di Android |
---|---|
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 K20e | 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 e modelli successivi (5G) | 9.0+ |
Samsung Galaxy S20 e modelli successivi | 9.0+ |
Samsung Galaxy S20 (5G) | 9.0+ |
Samsung Galaxy S20 Ultra 5G | 9.0+ |
Samsung Galaxy S20 | 9.0+ |
Samsung Galaxy Note 10 o versioni successive | 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 1a | 9.0+ |
Poco X2 | 9.0+ |
Sharp Aquos R3 SH-04L | 9.0+ |
Dispositivi per negozi, magazzini e centri di distribuzione
Produttore e modello | Versione di Android |
---|---|
Zebra PS20 | 10,0 e successive |
Zebra TC52/TC52HC | 10,0 e successive |
Zebra TC57 | 10,0 e successive |
Zebra TC72 | 10,0 e successive |
Zebra TC77 | 10,0 e successive |
Zebra MC93 | 10,0 e successive |
Zebra TC8300 | 10,0 e successive |
Zebra VC8300 | 10,0 e successive |
Zebra EC30 | 10,0 e successive |
Zebra ET51 | 10,0 e successive |
Zebra ET56 | 10,0 e successive |
Zebra L10 | 10,0 e successive |
Zebra CC600/CC6000 | 10,0 e successive |
Zebra MC3300x | 10,0 e successive |
Zebra MC330x | 10,0 e successive |
Zebra TC52x | 10,0 e successive |
Zebra TC57x | 10,0 e successive |
Zebra EC50 (LAN e HC) | 10,0 e successive |
Zebra EC55 (WAN) | 10,0 e successive |
Zebra WT6300 | 10,0 e successive |
Skorpio X5 | 10,0 e successive |