Posizione Wi-Fi: disponibile con RTT

Puoi utilizzare la funzionalità di geolocalizzazione Wi-Fi fornita dall'API Wi-Fi RTT (Round-Trip-Time) per misurare la distanza dai punti di accesso Wi-Fi compatibili con RTT e dai dispositivi peer Wi-Fi Aware nelle vicinanze.

Se misuri la distanza da tre o più punti di accesso, puoi utilizzare un algoritmo di trilaterazione per stimare la posizione del dispositivo più adatta a queste misurazioni. In genere il risultato è preciso entro 1-2 metri.

Con questa precisione, puoi sviluppare servizi basati sulla posizione granulari, come la navigazione al chiuso, il controllo vocale disambiguato (ad esempio, "Accendi questa lampada") e le informazioni basate sulla posizione (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 utilizzi questo protocollo per determinare la posizione di un dispositivo mediante la trilaterazione con dispositivi che eseguono Android 9, devi avere accesso ai dati predeterminati relativi alla posizione dei punti di accesso (AP) nella tua app. Sta a te decidere come memorizzare 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. In questo modo, la tua app può trovare gli AP e determinare le relative posizioni anche se non erano noti in precedenza, 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 tra le misurazioni di intervallo, lasciando l'intervallo esatto sotto il 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 misurazione della distanza 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 la richiesta di misurazione della distanza ha come target Android 13 (livello API 33) o versioni successive, deve disporre dell'autorizzazione NEARBY_WIFI_DEVICES. Se un'app di questo tipo ha come target una versione precedente di Android, deve invece avere l'autorizzazione ACCESS_FINE_LOCATION.
  • 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 ai dati sulla posizione in background.
  • Il punto di accesso deve implementare lo standard FTM IEEE 802.11-2016 o lo standard IEEE 802.11az (roaming 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. L'app dovrà richiedere l'autorizzazione dell'utente se non è già stata concessa. Per ulteriori informazioni sulle autorizzazioni di runtime, consulta Richiedi autorizzazioni app.

2. Verificare se il dispositivo supporta il RTT Wi-Fi

Per verificare se il dispositivo supporta la funzionalità 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

La funzionalità RTT Wi-Fi potrebbe essere presente sul dispositivo, ma potrebbe non essere disponibile perché l'utente ha disattivato il Wi-Fi. A seconda delle funzionalità hardware e del firmware, alcuni dispositivi potrebbero non supportare il RTT Wi-Fi se sono in uso SoftAP o il tethering. Per verificare se la funzionalità Wi-Fi RTT è disponibile, chiama isAvailable()

La disponibilità del 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 l'app riceve l'intent di trasmissione, deve controllare lo stato corrente della disponibilità e modificare il proprio comportamento di conseguenza.

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, consulta la sezione Trasmissioni.

Crea una richiesta di misurazione

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 addAccessPoints(List<ScanResult>) per aggiungere più punti di accesso in blocco.

Gli oggetti ScanResult possono contenere AP supportati sia con IEEE 802.11mc (is80211mcResponder()) sia con misurazione della distanza basata su trigger non IEEE 802.11az (is80211azNtbResponder()). 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 utilizzando il 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 sulla rilevazione dei peer Wi-Fi Aware, consulta la documentazione di Wi-Fi Aware.

Ricerca di intervalli

Un'app emette una richiesta di misurazione della distanza utilizzando il metodo WifiRttManager.startRanging() e fornendo quanto segue: un RangingRequest per specificare l'operazione, un Executor per specificare il contesto del callback e un 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 in RangingResultCallback. Questo tipo di errore può verificarsi se il servizio non è in grado di eseguire un'operazione di misurazione in quel momento, ad esempio perché il Wi-Fi è disattivato, perché l'applicazione ha richiesto troppe operazioni di misurazione ed è limitata o a causa di un problema di autorizzazione.
  • Quando l'operazione di rilevamento della distanza viene completata, 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 necessariamente all'ordine delle richieste. Tieni presente che l'operazione di misurazione della distanza potrebbe essere completata, ma ogni risultato potrebbe comunque indicare un errore di quella misurazione specifica.

Interpreta i risultati con intervallo

Ciascuno dei risultati restituiti onRangingResults è specificato da un RangingResult . Per ogni richiesta, svolgi le seguenti operazioni.

1. Identifica la richiesta

Identifica la richiesta in base alle informazioni fornite durante la creazione del RangingRequest: spesso un indirizzo MAC fornito nel ScanResult che identifica un punto di accesso. L'indirizzo MAC può essere ottenuto dal risultato del rilevamento utilizzando il metodo 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 misurazione:

    getDistanceMm()

    getDistanceStdDevMm()

  • RSSI dei pacchetti utilizzati per le misurazioni:

    getRssi()

  • Tempo in millisecondi in cui è stata eseguita la misurazione (indica il tempo dall'avvio):

    getRangingTimestampMillis()

  • Numero di misurazioni tentate e numero di misurazioni che hanno avuto esito positivo (e su cui si basano le misurazioni della distanza):

    getNumAttemptedMeasurements()

    getNumSuccessfulMeasurements()

  • Tempo minimo e massimo che un dispositivo client deve attendere tra due misurazioni NTB di 11 az:

    getMinTimeBetweenNtbMeasurementsMicros() e getMaxTimeBetweenNtbMeasurementsMicros() restituisce il tempo minimo e massimo. Se la misurazione di rilevamento successiva viene richiesta prima del tempo minimo, l'API restituisce il risultato del rilevamento 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 appieno l'efficienza della misurazione della distanza basata su trigger 802.11az, attiva la richiesta di misurazione della distanza successiva tra il tempo di misurazione minimo e massimo specificato nella misurazioneRangingResult precedente.

  • ripetizioni sul campo di addestramento lungo (LTF) che le stazioni di risposta e iniziatore utilizzato nel preambolo per il risultato dello standard IEEE 802.11az NTB:

    get80211azResponderTxLtfRepetitionsCount()

    get80211azInitiatorTxLtfRepetitionsCount()

  • 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:

    get80211azNumberOfTxSpatialStreams()

    get80211azNumberOfRxSpatialStreams()

Dispositivi Android che supportano Wi-Fi-RTT

Le seguenti tabelle elencano alcuni smartphone, punti di accesso e dispositivi per negozi, magazzini e centri di distribuzione che supportano WiFi-RTT. Questi dati 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 assistenza
Nest Wifi Pro (Wi-Fi 6E) Supportato
Compulab WILD AP Supportato
Google Wifi Supportato
Router Google Nest Wifi 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+ 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 1 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+
Zebra TC52/TC52HC 10,0 e successive
Zebra TC57 10,0 e successive
Zebra TC72 10.0+
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+
Zebra ET51 10.0+
Zebra ET56 10,0 e successive
Zebra L10 10.0+
Zebra CC600/CC6000 10,0 e successive
Zebra MC3300x 10.0+
Zebra MC330x 10.0+
Zebra TC52x 10.0+
Zebra TC57x 10.0+
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