Localisation en Wi-Fi: portée avec DAR

Vous pouvez utiliser la fonctionnalité de localisation Wi-Fi fournie par le API Wi-Fi RTT (Round-Trip-Time) pour mesurer la distance à proximité de points d'accès Wi-Fi compatibles avec le texte en temps réel et de pairs Appareils Wi-Fi Aware.

Si vous mesurez la distance à trois points d'accès ou plus, vous pouvez utiliser un l'algorithme de multilatération pour estimer la position de l'appareil la mieux adaptée des mesures. Le résultat est généralement précis à 1 ou 2 mètres près.

Grâce à cette précision, vous pouvez développer des services précis basés sur la localisation, tels que navigation intérieure, commande vocale clarifiée (par exemple, "Activez ce par exemple) et des informations liées à votre position (par exemple, "Existe-t-il des offres spéciales pour ce produit ?").

L'appareil à l'origine de la demande n'a pas besoin de se connecter aux points d'accès pour mesurer avec le DAR Wi-Fi. Pour des raisons de confidentialité, seul l'appareil à l'origine de la demande peut pour déterminer la distance jusqu'au point d'accès ; les points d'accès n'ont pas ces informations. Les opérations RTT Wi-Fi sont illimitées pour les applications au premier plan, mais limitées pour les applications en arrière-plan.

Le DAR Wi-Fi et les fonctionnalités de mesure du temps précis (FTM) associées sont spécifié par la norme IEEE 802.11-2016. Le texte en temps réel Wi-Fi nécessite l'heure précise est fournie par FTM, car il calcule la distance entre en mesurant le temps nécessaire à un paquet pour effectuer un aller-retour en multipliant ce temps par la vitesse de la lumière.

Android 15 (niveau d'API 35) est compatible avec la norme IEEE 802.11az non basée sur un déclencheur (NTB).

Différences d'implémentation selon la version d'Android

Le RTT Wi-Fi a été introduit dans Android 9 (niveau d'API 28). Lorsque vous utilisez ce protocole pour déterminer la position d'un appareil à l'aide de la multilatération avec des appareils exécutant Android 9, vous devez avoir accès aux données de localisation des points d'accès (PA) prédéterminés dans votre application. C'est à vous de décider comment stocker et récupérer ces données.

Sur les appareils équipés d'Android 10 (niveau d'API 29) ou version ultérieure, les données de localisation du point d'accès peuvent être représenté sous la forme ResponderLocation qui incluent la latitude, la longitude et l'altitude. Pour les points d'accès DAR Wi-Fi qui prendre en charge les informations de configuration d'emplacement/les rapports municipaux d'emplacement (données LCI/LCR) ; le protocole renvoie un objet ResponderLocation lors de la processus de mesure des distances.

Cette fonctionnalité permet aux applications d'interroger les points d'accès pour leur demander directement leur position, au lieu de devoir stocker ces informations à l'avance. Ainsi, votre application peut trouver des points d'accès et déterminer leur position même s'ils n'étaient pas connus auparavant, comme lorsqu'un utilisateur entre dans un nouveau bâtiment.

La prise en charge des distances NTB IEEE 802.11az est disponible sur les appareils équipés d'Android 15 (niveau d'API 35) ou version ultérieure. Cela signifie que si l'appareil est compatible avec IEEE 802.11az, Mode d'initiateur NTB (indiqué par WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_NTB_INITIATOR), votre application peut détecter des points d'accès compatibles avec IEEE 802.11mc et IEEE 802.11az avec un seul demande de plage d'adresses. L'API RangingResult a été étendue pour fournir des informations sur les valeurs minimale et maximale pouvant être utilisées pour l'intervalle entre en définissant une échelle de mesure, ce qui laisse l'intervalle exact aux commandes de votre application.

Conditions requises

  • Le matériel de l'appareil qui envoie la requête de mesure de la portée doit implémenter la norme FTM 802.11-2016 ou la norme 802.11az (mesure de la portée sans déclencheur).
  • L'appareil qui envoie la requête de mesure de la distance doit être équipé d'Android 9 (niveau d'API 28) ou version ultérieure. La mesure de la distance sans déclencheur IEEE 802.11az est activée sur les appareils équipés d'Android 15 (niveau d'API 35) ou version ultérieure.
  • Les services de localisation et la recherche Wi-Fi doivent être activés sur l'appareil qui envoie la requête de mesure de la distance (sous Settings > Location (Paramètres > Position)).
  • Si l'application qui effectue la demande de mesure des distances cible Android 13 (niveau d'API 33) ou version ultérieure, il doit disposer du NEARBY_WIFI_DEVICES l'autorisation. Si une telle application cible une version antérieure d'Android, elle doit ont la ACCESS_FINE_LOCATION l'autorisation à la place.
  • L'application doit interroger la plage de points d'accès lorsqu'elle est visible ou dans un service de premier plan. L'application ne peut pas accéder aux informations de localisation à partir du ou un arrière-plan.
  • Le point d'accès doit respecter la norme FTM IEEE 802.11-2016 ou la norme IEEE Norme 802.11az (mise à l'échelle non basée sur un déclencheur).

Configuration

Pour configurer votre application pour qu'elle utilise le RTT Wi-Fi, procédez comme suit :

1. Demander des autorisations

Demandez les autorisations suivantes dans le fichier manifeste de votre application:

<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" />

Les autorisations NEARBY_WIFI_DEVICES et ACCESS_FINE_LOCATION sont des autorisations dangereuses. Vous devez donc les demander au moment de l'exécution chaque fois que l'utilisateur souhaite effectuer une opération de numérisation RTT. Votre application devra demander l'autorisation autorisation si elle n'a pas déjà été accordée. Pour plus d'informations sur les autorisations d'exécution, consultez Demandez des autorisations d'application.

2. Vérifier si l'appareil est compatible avec le texte en temps réel via le Wi-Fi

Pour vérifier si l'appareil est compatible avec le DAR Wi-Fi, utilisez le API PackageManager:

Kotlin

context.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)

Java

context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);

3. Vérifier si le texte en temps réel via le Wi-Fi est disponible

Le DAR Wi-Fi peut exister sur l'appareil, mais il n'est peut-être pas disponible, car l'utilisateur a désactivé le Wi-Fi. Selon leurs capacités matérielles et logicielles, certains appareils peuvent ne pas prendre en charge le RTT Wi-Fi si le point d'accès virtuel ou le partage de connexion sont utilisés. Pour vérifier si le texte en temps réel Wi-Fi est disponible, appelez isAvailable()

La disponibilité du texte en temps réel Wi-Fi peut changer à tout moment. Votre application doit enregistrer un BroadcastReceiver pour recevoir ACTION_WIFI_RTT_STATE_CHANGED, qui est envoyé lorsque la disponibilité change. Lorsque votre application reçoit la diffusion l'application doit vérifier l'état actuel de la disponibilité et ajuster ses en conséquence.

Exemple :

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);

Pour en savoir plus, consultez la section Diffusions.

Créer une requête de mesure de la distance

Une requête de mesure de la portée (RangingRequest) est créée en spécifiant une liste d'AP ou de pairs Wi-Fi Aware auxquels une mesure de la portée est demandée. Vous pouvez spécifier plusieurs points d'accès ou pairs Wi-Fi Aware dans un une requête de télémétrie unique ; les distances entre tous les appareils sont mesurées et renvoyées.

Par exemple, une requête peut utiliser la méthode addAccessPoint() pour spécifier un point d'accès auquel mesurer la distance :

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 point d'accès est identifié par son objet ScanResult, qui peut être obtenu en appelant WifiManager.getScanResults() Vous pouvez utiliser addAccessPoints(List<ScanResult>) pour ajouter plusieurs points d'accès en lot.

Les objets ScanResult peuvent contenir à la fois IEEE 802.11mc (is80211mcResponder()) et Compatibilité avec les distances (is80211azNtbResponder()) basées sur la norme IEEE 802.11az non basée sur un déclencheur les points d'accès. Les appareils compatibles avec la norme IEEE 802.11az NTB avec des spécifications 802.11mc ou 802.11az, allant en fonction de la capacité du point d'accès, 802.11az par défaut lorsque le point d'accès prend en charge les deux. Les appareils qui ne sont pas compatibles avec la norme IEEE 802.11az effectuent toutes les mesures de portée à l'aide du protocole IEEE 802.11mc.

De même, une demande de télémétrie peut ajouter un pair Wi-Fi Aware à l'aide de son adresse MAC ou son PeerHandle, en utilisant la addWifiAwarePeer(MacAddress peer) et addWifiAwarePeer(PeerHandle peer) . Pour en savoir plus sur la découverte des pairs Wi-Fi Aware, consultez la documentation Wi-Fi Aware.

Évaluation de la portée des requêtes

Une application émet une requête de mesure de distance à l'aide du WifiRttManager.startRanging() et en fournissant les éléments suivants : RangingRequest pour spécifier le opération, un Executor pour spécifier le contexte de rappel RangingResultCallback pour recevoir les résultats.

Exemple :

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'opération de mesure de la portée est effectuée de manière asynchrone, et les résultats de mesure de la portée sont renvoyés dans l'un des rappels de RangingResultCallback :

  • Si l'ensemble de l'opération de mesure des distances échoue, onRangingFailure est déclenché avec un code d'état décrit dans RangingResultCallback Un tel échec peut se produire si le service ne peut pas exécuter une opération de mesure de la distance à ce moment-là (par exemple, si le Wi-Fi est désactivé, si l'application a demandé trop d'opérations de mesure de la distance et est limitée, ou en raison d'un problème d'autorisation).
  • Une fois l'opération de mesure des distances terminée, onRangingResults est déclenché avec une liste de résultats correspondant à la liste des requêtes) : un résultat par requête. L'ordre des résultats ne correspond pas nécessairement à l'ordre des requêtes. Notez que l'opération de mesure des distances mais chaque résultat peut tout de même indiquer une défaillance les mesures.

Interpréter les résultats des distances

Chacun des résultats renvoyés par onRangingResults rappel est spécifié par un RangingResult . Pour chaque requête, procédez comme suit :

1. Identifier la demande

Identifiez la demande d'après les informations fournies lors de la création de la RangingRequest: le plus souvent, une adresse MAC fournie dans le ScanResult identifiant un accès point d'accès. L'adresse MAC peut être obtenue à partir du résultat de la mesure de la portée à l'aide de la méthode getMacAddress().

La liste des résultats de la mesure de la portée peut être dans un ordre différent de celui des pairs (points d'accès) spécifiés dans la requête de mesure de la portée. Vous devez donc utiliser l'adresse MAC pour identifier le pair, et non l'ordre des résultats.

2. Déterminer si chaque mesure a réussi

Pour déterminer si une mesure a réussi, utilisez la méthode getStatus(). Toute valeur autre que STATUS_SUCCESS indique un échec. Un échec signifie que tous les autres champs de ce résultat (à l'exception de l'identification de la requête ci-dessus) sont non valides, et la méthode get* correspondante échouera avec une exception IllegalStateException.

3. Obtenir des résultats pour chaque mesure réussie

Pour chaque mesure réussie (RangingResult), vous pouvez récupérer les valeurs de résultat à l'aide des méthodes get respectives :

  • Distance, en mm, et écart type de la mesure :

    getDistanceMm()

    getDistanceStdDevMm()

  • RSSI des paquets utilisés pour les mesures:

    getRssi()

  • Heure, en millisecondes, à laquelle la mesure a été effectuée (il s'agit de l'heure depuis le démarrage):

    getRangingTimestampMillis()

  • Nombre de mesures effectuées et nombre de mesures réussies (sur lesquelles les mesures de distance sont basées) :

    getNumAttemptedMeasurements()

    getNumSuccessfulMeasurements()

  • Durée minimale et maximale d'attente d'un appareil client entre deux mesures NTB 11az :

    getMinTimeBetweenNtbMeasurementsMicros() et getMaxTimeBetweenNtbMeasurementsMicros() renvoie la durée minimale et maximale. Si la mesure suivante de la mesure des distances est avant l'expiration du délai minimal, l'API renvoie la mis en cache le résultat de la plage. Si la mesure de la mesure de distance suivante est demandée après le temps maximal s'est écoulé, l'API arrête l'événement non déclencheur de la session de définition des distances et négocie une nouvelle session avec la personne interrogée . Vous devez éviter de demander une nouvelle session de mesure des distances, car cela ajoute sur la durée de la mesure des distances. Pour exploiter pleinement l'efficacité de la mesure de la portée basée sur des déclencheurs 802.11az, déclenchez la prochaine requête de mesure de la portée entre la durée de mesure minimale et maximale spécifiée dans la mesure RangingResult précédente.

  • Répétions du champ de formation long (LTF) que les stations de réponse et d'initiation ont utilisées dans le préambule pour le résultat NTB IEEE 802.11az :

    get80211azResponderTxLtfRepetitionsCount()

    get80211azInitiatorTxLtfRepetitionsCount()

  • Nombre de flux temporels spatiaux (STS) d'émission et de réception que la station d'initiateur a utilisés pour le résultat NTB IEEE 802.11az :

    get80211azNumberOfTxSpatialStreams()

    get80211azNumberOfRxSpatialStreams()

Appareils Android compatibles avec WiFi-RTT

Les tableaux suivants répertorient certains téléphones, points d'accès et appareils de point de vente, d'entrepôt et de centre de distribution compatibles avec le WiFi-RTT. Ces outils sont loin d'être exhaustifs. Nous vous encourageons à nous contacter pour répertorier ici vos produits compatibles avec le texte en temps réel.

Points d'accès

Fabricant et modèle Date de prise en charge
Nest Wifi Pro (Wi-Fi 6E) Compatible
Compulab WILD AP Compatible
Google Wifi Compatible
Routeur Wi-Fi Google Nest Compatible
Point d'accès Google Nest Wifi Compatible
Aruba AP-635 Compatible
Cisco 9130 Compatible
Cisco 9136 Compatible
Cisco 9166 Compatible
Cisco 9164 Compatible
Aruba AP-505 Compatible
Aruba AP-515 Compatible
Aruba AP-575 Compatible
Aruba AP-518 Compatible
Aruba AP-505H Compatible
Aruba AP-565 Compatible
Aruba AP-535 Compatible

Téléphones

Fabricant et modèle Version d'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 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+ 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+

Appareils pour les magasins, les entrepôts et les centres de distribution

Fabricant et modèle Version d'Android
Zebra PS20 10,0 et supérieures
Zebra TC52/TC52HC 10,0 et supérieures
Zebra TC57 10,0 et supérieures
Zebra TC72 10,0 et supérieures
Zebra TC77 10,0 et supérieures
Zebra MC93 10,0 et supérieures
Zebra TC8300 10,0 et supérieures
Zebra VC8300 10,0 et supérieures
Zebra EC30 10,0 et supérieures
Zebra ET51 10,0 et supérieures
Zebra ET56 10,0 et supérieures
Zebra L10 10,0 et supérieures
Zebra CC600/CC6000 10,0 et supérieures
Zebra MC3300x 10,0 et supérieures
Zebra MC330x 10,0 et supérieures
Zebra TC52x 10,0 et supérieures
Zebra TC57x 10,0 et supérieures
Zebra EC50 (LAN et HC) 10,0 et supérieures
Zebra EC55 (WAN) 10,0 et supérieures
Zebra WT6300 10,0 et supérieures
Skorpio X5 10,0 et supérieures