Posizione Wi-Fi: disponibile con RTT

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.

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.

Requisiti

  • L'hardware del dispositivo che effettua la richiesta di portata deve implementare il parametro 802.11-2016 FTM standard.
  • Sul dispositivo che effettua la richiesta di portata deve essere installato Android 9 (livello API) 28) o 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 avere ACCESS_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.

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 al momento potrebbe non essere disponibile perché l'utente ha disattivato il Wi-Fi. In base all'hardware e al firmware alcune funzionalità, alcuni dispositivi potrebbero non supportare Wi-Fi RTT se SoftAP o tethering sono in uso. 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 RicevitoreTrasmissione 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) viene creato da che specifica 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(Elenco) per aggiungere più punti di accesso in un batch.

Allo stesso modo, una richiesta di portata può aggiungere un peer Wi-Fi Aware utilizzando il suo MAC o il relativo PeerHandle, utilizzando il addWifiAwarePeer(peer MacAddress) 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 esecutore 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 in RangingResultCallback. 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 valore 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 STATO_SUCCESSO 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 Eccezione legalStateException .

3. Ottieni risultati per ogni misurazione riuscita

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

Dispositivi Android che supportano Wi-Fi-RTT

Le tabelle riportate di seguito 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 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 e oltre
Pixel 6 Pro 9,0 e oltre
Pixel 5 9,0 e oltre
Pixel 5a 9,0 e oltre
Pixel 5a (5G) 9,0 e oltre
Xiaomi Mi 10 Pro 9,0 e oltre
Xiaomi Mi 10 9,0 e oltre
Xiaomi Redmi Mi 9T Pro 9,0 e oltre
Xiaomi Mi 9T 9,0 e oltre
Xiaomi Mi 9 9,0 e oltre
Xiaomi Mi Note 10 9,0 e oltre
Xiaomi Mi Note 10 Lite 9,0 e oltre
Xiaomi Redmi Note 9S 9,0 e oltre
Xiaomi Redmi Note 9 Pro 9,0 e oltre
Xiaomi Redmi Note 8T 9,0 e oltre
Xiaomi Redmi Note 8 9,0 e oltre
Xiaomi Redmi K30 Pro 9,0 e oltre
Xiaomi Redmi K20 Pro 9,0 e oltre
Xiaomi Redmi K20e 9,0 e oltre
Xiaomi Redmi Note 5 Pro 9,0 e oltre
Xiaomi Mi CC9 Pro 9,0 e oltre
LG G8X ThinQ 9,0 e oltre
LG V50S ThinQ 9,0 e oltre
LG V60 ThinQ 9,0 e oltre
LG V30 9,0 e oltre
Samsung Galaxy Note 10+ 5G 9,0 e oltre
Samsung Galaxy S20 e modelli successivi (5G) 9,0 e oltre
Samsung Galaxy S20 e modelli successivi 9,0 e oltre
Samsung Galaxy S20 (5G) 9,0 e oltre
Samsung Galaxy S20 Ultra 5G 9,0 e oltre
Samsung Galaxy S20 9,0 e oltre
Samsung Galaxy Note 10 o versioni successive 9,0 e oltre
Samsung Galaxy Note 10 (5G) 9,0 e oltre
Samsung Galaxy Note 10 9,0 e oltre
Samsung A9 Pro 9,0 e oltre
Google Pixel 4 XL 9,0 e oltre
Google Pixel 4 9,0 e oltre
Google Pixel 4a 9,0 e oltre
Google Pixel 3 XL 9,0 e oltre
Google Pixel 3 9,0 e oltre
Google Pixel 3a XL 9,0 e oltre
Google Pixel 3a 9,0 e oltre
Google Pixel 2 XL 9,0 e oltre
Google Pixel 2 9,0 e oltre
Google Pixel 1 XL 9,0 e oltre
Google Pixel 1a 9,0 e oltre
Poco X2 9,0 e oltre
Sharp Aquos R3 SH-04L 9,0 e oltre

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