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 nelle vicinanze che supportano RTT e dai dispositivi peer 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 queste misurazioni. Il risultato è in genere preciso entro 1-2 metri.

Con questa precisione, puoi sviluppare servizi granulari e basati sulla posizione geografica, come la navigazione interna, il controllo vocale chiaro (ad es. "Accendi questa luce") e informazioni basate sulla località (ad esempio "Sono disponibili offerte speciali per questo prodotto?").

Il dispositivo richiedente non deve connettersi ai punti di accesso per misurare la distanza con RTT Wi-Fi. Per mantenere la privacy, solo il dispositivo richiedente è in grado di determinare la distanza dal punto di accesso; i punti di accesso non dispongono di queste informazioni. Le operazioni RTT Wi-Fi sono illimitate per le app in primo piano, ma sono limitate per le app in background.

Wi-Fi RTT e le relative funzionalità di Fine-Time Measurement (FTM) sono specificate dallo standard IEEE 802.11-2016. La funzionalità RTT Wi-Fi richiede la misurazione del tempo precisa fornita da FTM perché calcola la distanza tra due dispositivi misurando il tempo impiegato da un pacchetto per fare un round trip tra i dispositivi e moltiplicando questo tempo per la velocità della luce.

Differenze di implementazione in base alla versione di Android

La funzionalità RTT Wi-Fi è stata introdotta in Android 9 (livello API 28). Quando utilizzi questo protocollo per determinare la posizione di un dispositivo mediante la multilaterazione con dispositivi con Android 9, devi avere accesso ai dati sulle posizioni dei punti di accesso (AP) predeterminati nella tua app. Sta a te 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 rappresentati come oggetti ResponderLocation, che includono latitudine, longitudine e altitudine. Per gli AP Wi-Fi RTT che supportano le informazioni sulla configurazione della località/il report civico sulla posizione (dati LCI/LCR), il protocollo restituirà un oggetto ResponderLocation durante il processo di gestione.

Questa funzionalità consente alle app di interrogare gli AP per chiedere direttamente la loro posizione invece di dover memorizzare queste informazioni in anticipo. Ciò significa che l'app può trovare gli AP e determinarne la posizione anche se prima non lo conoscevano, ad esempio quando un utente entra in un nuovo edificio.

Requisiti

  • L'hardware del dispositivo che effettua la richiesta di distanza deve implementare lo standard FTM 802.11-2016.
  • Il dispositivo che effettua la richiesta di intervallo deve eseguire Android 9 (livello API 28) o versioni successive.
  • Sul dispositivo che effettua la richiesta di rilevamento del rilevamento devono essere attivi i servizi di geolocalizzazione e la ricerca di reti Wi-Fi (in Impostazioni > Posizione).
  • Se l'app che effettua la richiesta di rilevamento ha come target Android 13 (livello API 33) o versioni successive, deve avere l'autorizzazione NEARBY_WIFI_DEVICES. Se un'app di questo tipo ha come target una versione precedente di Android, deve avere invece l'autorizzazione ACCESS_FINE_LOCATION.
  • L'app deve eseguire query sull'intervallo di punti di accesso quando è visibile o in un servizio in primo piano. L'app non può accedere alle informazioni sulla posizione in background.
  • Il punto di accesso deve implementare lo standard FTM IEEE 802.11-2016.

Configura

Per configurare l'app per l'utilizzo della funzionalità RTT Wi-Fi, svolgi i passaggi che seguono.

1. Richiedi autorizzazioni

Richiedi le autorizzazioni seguenti 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 autorizzazioni pericolose, perciò devi richiederle in fase di runtime ogni volta che l'utente vuole eseguire un'operazione di scansione RTT. Se l'autorizzazione non è già stata concessa, l'app dovrà richiedere l'autorizzazione dell'utente. Per saperne di più sulle autorizzazioni di runtime, consulta Richiedere autorizzazioni app.

2. Verificare se il dispositivo supporta la funzionalità RTT Wi-Fi

Per verificare se il dispositivo supporta la funzionalità RTT Wi-Fi, utilizza l'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 attualmente disponibile perché l'utente ha disattivato il Wi-Fi. A seconda delle funzionalità hardware e firmware, alcuni dispositivi potrebbero non supportare la tecnologia RTT Wi-Fi se sono in uso le funzionalità SoftAP o il tethering. Per verificare se la funzionalità RTT Wi-Fi è attualmente disponibile, chiama isAvailable().

La disponibilità della funzionalità RTT Wi-Fi può variare in qualsiasi momento. L'app deve registrare un BroadcastRicevir per ricevere ACTION_WIFI_RTT_STATE_CHANGED, che viene inviata quando la disponibilità cambia. Quando l'app riceve l'intent di trasmissione, deve controllare lo stato attuale di disponibilità e regolarne il comportamento di conseguenza.

Ecco alcuni esempi:

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 di intervallo

Una richiesta di intervallo (RangingRequest) viene creata specificando un elenco di punti di accesso o peer Wi-Fi Aware a cui viene richiesto un intervallo. È possibile specificare più punti di accesso o peer Wi-Fi Aware in una singola richiesta di distanza; le distanze da tutti i dispositivi vengono misurate e restituite.

Ad esempio, una richiesta può utilizzare il metodo addAccessPoint() per specificare un punto di accesso al quale 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 viene identificato dal relativo oggetto ScanResult, che può essere ottenuto chiamando WifiManager.getScanResults(). Puoi utilizzare addAccessPoints(List) per aggiungere più punti di accesso in un batch.

Allo stesso modo, una richiesta di intervallo può aggiungere un peer Wi-Fi Aware utilizzando il relativo indirizzo MAC o il suo PeerHandle, rispettivamente utilizzando i metodi addWifiAwarePeer(MacAddress peer) e addWifiAwarePeer(PeerHandle peer). Per ulteriori informazioni sulla scoperta dei peer Wi-Fi Aware, consulta la documentazione relativa a Wi-Fi Aware.

Intervallo richiesta

Un'app invia una richiesta di intervallo utilizzando il metodo WifiRttManager.startRanging() e fornendo quanto segue: un RangingRequest per specificare l'operazione, un esecutore per specificare il contesto di callback e un RangingResultCallback per ricevere i risultati.

Ecco alcuni esempi:

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 vengono restituiti in uno dei callback di RangingResultCallback:

  • Se l'intera operazione di rilevamento non riesce, il callback onRangingFailure viene attivato con un codice di stato descritto in RangingResultCallback. Questo errore può verificarsi se il servizio non può eseguire un'operazione di rilevamento della distanza in un determinato momento, ad esempio perché il Wi-Fi è disattivato, perché l'applicazione ha richiesto troppe operazioni di rilevamento del segnale ed è limitata o a causa di un problema di autorizzazione.
  • Al completamento dell'operazione di intervallo, il callback onRangingResults viene attivato con un elenco di risultati che corrispondono all'elenco delle richieste, ovvero un risultato per ogni richiesta. L'ordine dei risultati non corrisponde necessariamente all'ordine delle richieste. Tieni presente che l'operazione di rilevamento della distanza potrebbe essere completata, ma ogni risultato potrebbe comunque indicare un errore di quella misurazione specifica.

Interpretare i risultati della distanza

Ciascun risultato restituito dal callback onRangingResults viene specificato da un oggetto RangingResult. Per ogni richiesta:

1. Identifica la richiesta

Identifica la richiesta in base alle informazioni fornite durante la creazione di RangingRequest: il più delle volte un indirizzo MAC fornito in ScanResult che identifica un punto di accesso. L'indirizzo MAC può essere ottenuto dal risultato della gamma utilizzando il metodo getMacAddress().

L'elenco dei risultati di intervallo potrebbe essere in un ordine diverso rispetto ai peer (punti di accesso) specificati nella richiesta di intervallo, quindi devi utilizzare 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 il metodo getStatus(). Qualsiasi valore diverso da STATUS_SUCCESS indica un errore. Un errore indica che tutti gli altri campi di questo risultato (ad eccezione dell'identificazione della richiesta sopra riportata) non sono validi e il metodo get* corrispondente non riuscirà con un'eccezione PriorityStateException .

3. Ottieni risultati per ogni misurazione riuscita

Per ogni misurazione riuscita, puoi recuperare i valori dei risultati con i rispettivi metodi get:

Dispositivi Android che supportano il Wi-Fi-RTT

Nelle tabelle che seguono sono elencati alcuni telefoni, punti di accesso e dispositivi per centri di vendita al dettaglio, magazzinaggio e centri di distribuzione che supportano il Wi-Fi-RTT. Queste informazioni sono tutt'altro che complete. Ti invitiamo a contattarci per elencare qui i tuoi prodotti RTT.

Punti di accesso

Produttore e modello Data del supporto
Nest Wifi Pro (Wi-Fi 6E) Prove di supporto
AP WILD Compulab Prove di supporto
Google Wi-Fi Prove di supporto
Router Wi-Fi Google Nest Prove di supporto
Punto di accesso Wi-Fi Google Nest Prove di supporto
Aruba AP-635 Prove di supporto
Cisco 9130 Prove di supporto
Cisco 9136 Prove di supporto
Cisco 9166 Prove di supporto
Cisco 9164 Prove di supporto
Aruba AP-505 Prove di supporto
Aruba AP-515 Prove di supporto
Aruba AP-575 Prove di supporto
Aruba AP-518 Prove di supporto
Aruba AP-505H Prove di supporto
Aruba AP-565 Prove di supporto
Aruba AP-535 Prove di supporto

Smartphone

Produttore e modello Versione di Android
Pixel 6 Più di 9,0
Pixel 6 Pro Più di 9,0
Pixel 5 Più di 9,0
Pixel 5a Più di 9,0
Pixel 5a (5G) Più di 9,0
Xiaomi Mi 10 Pro Più di 9,0
Xiaomi Mi 10 Più di 9,0
Xiaomi Redmi Mi 9T Pro Più di 9,0
Xiaomi Mi 9T Più di 9,0
Xiaomi Mi 9 Più di 9,0
Xiaomi Mi Note 10 Più di 9,0
Xiaomi Mi Note 10 Lite Più di 9,0
Xiaomi Redmi Note 9S Più di 9,0
Xiaomi Redmi Note 9 Pro Più di 9,0
Xiaomi Redmi Note 8T Più di 9,0
Xiaomi Redmi Note 8 Più di 9,0
Xiaomi Redmi K30 Pro Più di 9,0
Xiaomi Redmi K20 Pro Più di 9,0
Xiaomi Redmi K20 Più di 9,0
Xiaomi Redmi Note 5 Pro Più di 9,0
Xiaomi Mi CC9 Pro Più di 9,0
LG G8X ThinQ Più di 9,0
LG V50S ThinQ Più di 9,0
LG V60 ThinQ Più di 9,0
LG V30 Più di 9,0
Samsung Galaxy Note 10+ 5G Più di 9,0
Samsung Galaxy S20+ 5G Più di 9,0
Samsung Galaxy S20 e modelli successivi Più di 9,0
Samsung Galaxy S20 5G Più di 9,0
Samsung Galaxy S20 Ultra 5G Più di 9,0
Samsung Galaxy S20 Più di 9,0
Samsung Galaxy Note 10 e modelli successivi Più di 9,0
Samsung Galaxy Note 10 (5G) Più di 9,0
Samsung Galaxy Note 10 Più di 9,0
Samsung A9 Pro Più di 9,0
Google Pixel 4 XL Più di 9,0
Google Pixel 4 Più di 9,0
Google Pixel 4a Più di 9,0
Google Pixel 3 XL Più di 9,0
Google Pixel 3 Più di 9,0
Google Pixel 3a XL Più di 9,0
Google Pixel 3a Più di 9,0
Google Pixel 2 XL Più di 9,0
Google Pixel 2 Più di 9,0
Google Pixel 1 XL Più di 9,0
Google Pixel 1 Più di 9,0
Poco X2 Più di 9,0
Sharp Aquos R3 SH-04L Più di 9,0

Dispositivi per vendita al dettaglio, stoccaggio e centri di distribuzione

Produttore e modello Versione di Android
Zebra PS20 Più di 10,0
Zebra TC52/TC52HC Più di 10,0
Zebra TC57 Più di 10,0
Zebra TC72 Più di 10,0
Zebra TC77 Più di 10,0
Zebra MC93 Più di 10,0
Zebra TC8300 Più di 10,0
Zebra VC8300 Più di 10,0
Zebra EC30 Più di 10,0
Zebra ET51 Più di 10,0
Zebra ET56 Più di 10,0
Zebra L10 Più di 10,0
Zebra CC600/CC6000 Più di 10,0
Zebra MC3300x Più di 10,0
Zebra MC330x Più di 10,0
Zebra TC52x Più di 10,0
Zebra TC57x Più di 10,0
Zebra EC50 (LAN e HC) Più di 10,0
Zebra EC55 (WAN) Più di 10,0
Zebra WT6300 Più di 10,0
Skorpio X5 Più di 10,0