Vous pouvez utiliser la fonctionnalité de localisation Wi-Fi fournie par l'API Wi-Fi RTT (Round-Trip-Time) pour mesurer la distance par rapport aux points d'accès Wi-Fi compatibles avec RTT et aux appareils Wi-Fi Aware à proximité.
Si vous mesurez la distance par rapport à trois points d'accès ou plus, vous pouvez utiliser un algorithme de multilateration pour estimer la position de l'appareil qui correspond le mieux à ces mesures. Le résultat est généralement précis à un ou deux mètres près.
Grâce à cette précision, vous pouvez développer des services basés sur la localisation très précis, comme la navigation en intérieur, le contrôle vocal non ambigu (par exemple, "Allume cette lumière") et les informations basées sur la localisation (par exemple, "Y a-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 la distance avec le Wi-Fi RTT. Pour préserver la confidentialité, seul l'appareil demandeur est en mesure de déterminer la distance par rapport au point d'accès. Les points d'accès ne disposent pas de cette information. Les opérations Wi-Fi RTT sont illimitées pour les applications au premier plan, mais sont limitées pour les applications en arrière-plan.
Le Wi-Fi RTT et les fonctionnalités Fine-Time-Measurement (FTM) associées sont spécifiés par la norme IEEE 802.11-2016. Le Wi-Fi RTT nécessite la mesure précise du temps fournie par FTM, car il calcule la distance entre deux appareils en mesurant le temps qu'un paquet met à faire l'aller-retour entre les appareils et en multipliant ce temps par la vitesse de la lumière.
Android 15 (niveau d'API 35) est compatible avec la mesure de distance IEEE 802.11az non basée sur le déclenchement (NTB).
Différences d'implémentation selon la version d'Android
Le Wi-Fi RTT 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 multilateration 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 des points d'accès peuvent être représentées sous forme d'objets ResponderLocation
, qui incluent la latitude, la longitude et l'altitude. Pour les points d'accès Wi-Fi RTT compatibles avec les données LCI/LCR (Location Configuration Information/Location Civic Report), le protocole renvoie un objet ResponderLocation
lors du processus de mesure de distance.
Cette fonctionnalité permet aux applications d'interroger les points d'accès pour leur demander leur position directement, sans avoir à stocker ces informations à l'avance. Votre application peut ainsi trouver des points d'accès et déterminer leur position, même s'ils n'étaient pas connus auparavant, par exemple lorsqu'un utilisateur entre dans un nouveau bâtiment.
La prise en charge de la mesure de distance 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 le mode initiateur NTB IEEE 802.11az (indiqué par WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_NTB_INITIATOR
), votre application peut trouver les points d'accès compatibles avec IEEE 802.11mc et IEEE 802.11az avec une seule demande de plage. L'API RangingResult
a été étendue pour fournir des informations sur les valeurs minimale et maximale pouvant être utilisées pour l'intervalle entre les mesures de distance, laissant l'intervalle exact sous le contrôle de votre application.
Conditions requises
- Le matériel de l'appareil qui envoie la demande de mesure de distance doit implémenter la norme FTM 802.11-2016 ou la norme 802.11az (mesure de distance non basée sur un déclencheur).
- L'appareil qui envoie la demande de mesure de distance doit être équipé d'Android 9 (niveau d'API 28) ou version ultérieure. La mesure de distance non basée sur le déclenchement 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 (sous Paramètres > Localisation) doivent être activés sur l'appareil qui effectue la demande de mesure de distance.
- Si l'application qui effectue la demande de mesure de distance cible Android 13 (niveau d'API 33) ou version ultérieure, elle doit disposer de l'autorisation
NEARBY_WIFI_DEVICES
. Si une telle application cible une version antérieure d'Android, elle doit disposer de l'autorisationACCESS_FINE_LOCATION
. - 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 en arrière-plan.
- Le point d'accès doit implémenter la norme IEEE 802.11-2016 FTM ou la norme IEEE 802.11az (mesure de distance non basée sur un déclencheur).
Configuration
Pour configurer votre application afin qu'elle utilise Wi-Fi RTT, 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 d'analyse RTT. Votre application devra demander l'autorisation à l'utilisateur si elle ne l'a pas déjà obtenue. Pour en savoir plus sur les autorisations d'exécution, consultez Exiger des autorisations d'applications.
2. Vérifiez si l'appareil est compatible avec le Wi-Fi RTT.
Pour vérifier si l'appareil est compatible avec le Wi-Fi RTT, utilisez l'API PackageManager
:
Kotlin
context.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)
Java
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);
3. Vérifier si Wi-Fi RTT est disponible
Le Wi-Fi RTT peut exister sur l'appareil, mais il peut ne pas être disponible, car l'utilisateur a désactivé le Wi-Fi. En fonction des capacités de leur matériel et de leur micrologiciel, il est possible que certains appareils ne soient pas compatibles avec le Wi-Fi RTT si SoftAP ou le partage de connexion sont utilisés. Pour vérifier si le Wi-Fi RTT est disponible, appelez isAvailable()
.
La disponibilité de Wi-Fi RTT 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 l'intent de diffusion, elle doit vérifier l'état de disponibilité actuel et ajuster son comportement 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 Diffusions.
Créer une demande de gamme
Une demande de mesure de distance (RangingRequest
) est créée en spécifiant une liste de points d'accès ou de pairs Wi-Fi Aware pour lesquels une distance est demandée. Plusieurs points d'accès ou pairs Wi-Fi Aware peuvent être spécifiés dans une même demande de mesure de distance. Les distances à 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 à partir duquel 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 par lot.
Les objets ScanResult
peuvent contenir des points d'accès compatibles avec la mesure de distance non basée sur le déclencheur IEEE 802.11az (is80211azNtbResponder()
) et IEEE 802.11mc (is80211mcResponder()
). Les appareils compatibles avec la mesure de distance NTB IEEE 802.11az effectuent une mesure de distance 802.11mc ou 802.11az en fonction des capacités du point d'accès, en utilisant par défaut la mesure de distance 802.11az lorsque le point d'accès est compatible avec les deux. Les appareils qui ne sont pas compatibles avec la norme IEEE 802.11az effectuent toutes les mesures de distance à l'aide du protocole IEEE 802.11mc.
De même, une demande de mesure de distance peut ajouter un pair Wi-Fi Aware à l'aide de son adresse MAC ou de son PeerHandle
, en utilisant respectivement les méthodes 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.
Demander une mesure de distance
Une application émet une requête de mesure de distance à l'aide de la méthode WifiRttManager.startRanging()
et fournit les éléments suivants : un RangingRequest
pour spécifier l'opération, un Executor
pour spécifier le contexte de rappel et un 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 distance est effectuée de manière asynchrone, et les résultats de la mesure de distance sont renvoyés dans l'un des rappels de RangingResultCallback
:
- Si l'ensemble de l'opération de mesure de distance échoue, le rappel
onRangingFailure
est déclenché avec un code d'état décrit dansRangingResultCallback
. Un tel échec peut se produire si le service ne peut pas exécuter d'opération de mesure de distance au moment donné, par exemple parce que le Wi-Fi est désactivé, parce que l'application a demandé trop d'opérations de mesure de distance et est limitée, ou en raison d'un problème d'autorisation. - Une fois l'opération de mesure de distance terminée, le rappel
onRangingResults
est déclenché avec une liste de résultats correspondant à la liste des requêtes (un résultat pour chaque requête). L'ordre des résultats ne correspond pas nécessairement à celui des requêtes. Notez que l'opération de mesure de distance peut se terminer, mais que chaque résultat peut toujours indiquer un échec de cette mesure spécifique.
Interpréter les résultats de la mesure de distance
Chacun des résultats renvoyés par le rappel onRangingResults
est spécifié par un objet RangingResult
. Pour chaque demande, procédez comme suit :
1. Identifier la demande
Identifiez la requête en fonction des informations fournies lors de la création de RangingRequest
: le plus souvent, il s'agit d'une adresse MAC fournie dans ScanResult
identifiant un point d'accès. L'adresse MAC peut être obtenue à partir du résultat de la mesure de distance à l'aide de la méthode getMacAddress()
.
L'ordre de la liste des résultats de mesure de distance peut être différent de celui des pairs (points d'accès) spécifiés dans la demande de mesure de distance. 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) ne sont pas valides et que la méthode get*
correspondante échouera avec une exception IllegalStateException
.
3. Obtenir les résultats de chaque mesure réussie
Pour chaque mesure réussie (RangingResult
), vous pouvez récupérer les valeurs de résultat avec les méthodes get
respectives :
Distance, en mm, et écart-type de la mesure :
RSSI des paquets utilisés pour les mesures :
Heure (en millisecondes) à laquelle la mesure a été effectuée (indiquant le temps écoulé depuis le démarrage) :
Nombre de mesures tentées et nombre de mesures réussies (sur lesquelles sont basées les mesures de distance) :
Temps minimal et maximal qu'un appareil client doit attendre entre les mesures NTB 11az :
getMinTimeBetweenNtbMeasurementsMicros()
etgetMaxTimeBetweenNtbMeasurementsMicros()
renvoient respectivement la durée minimale et maximale. Si la prochaine mesure de distance est demandée avant l'expiration du délai minimal, l'API renvoie le résultat de mesure de distance mis en cache. Si la prochaine mesure de distance est demandée après l'expiration du délai maximal, l'API met fin à la session de mesure de distance sans déclencheur et négocie une nouvelle session de mesure de distance avec la station répondante. Évitez de demander une nouvelle session de mesure de distance, car cela ajoute de la surcharge au temps de mesure de distance. Pour profiter pleinement de l'efficacité de la mesure de distance basée sur 802.11az sans déclencheur, déclenchez la prochaine demande de mesure de distance entre la durée de mesure minimale et maximale spécifiée dans la mesureRangingResult
précédente.Répétitions du champ d'entraînement 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 :
Nombre de flux temporels spatiaux (STS) d'émission et de réception utilisés par la station initiatrice pour le résultat NTB IEEE 802.11az :
Appareils Android compatibles avec le Wi-Fi RTT
Les tableaux suivants listent certains téléphones, points d'accès et appareils pour les magasins, les entrepôts et les centres de distribution compatibles avec le Wi-Fi RTT. Elles sont loin d'être exhaustives. Nous vous encourageons à nous contacter pour que nous ajoutions vos produits compatibles avec la technologie RTT à cette liste.
Points d'accès
Fabricant et modèle | Date de compatibilité | Protocole |
---|---|---|
Nest Wifi Pro (Wi-Fi 6E) | Compatible | mc |
Compulab WILD AP | Compatible | mc |
Google Wifi | Compatible | mc |
Routeur Google Nest Wifi | Compatible | mc |
Point d'accès Google Nest Wifi | Compatible | mc |
Aruba AP-635 | Compatible | mc |
Cisco 9130 | Compatible | mc |
Cisco 9136 | Compatible | mc |
Cisco 9166 | Compatible | mc |
Cisco 9164 | Compatible | mc |
Cisco CW9172I | Compatible | mc/az |
Cisco CW9172H | Compatible | mc/az |
Cisco CW9176I | Compatible | mc/az |
Cisco CW9178I | Compatible | mc/az |
Aruba AP-505 | Compatible | mc |
Aruba AP-515 | Compatible | mc |
Aruba AP-575 | Compatible | mc |
Aruba AP-518 | Compatible | mc |
Aruba AP-505H | Compatible | mc |
Aruba AP-565 | Compatible | mc |
Aruba AP-535 | Compatible | mc |
Aruba AP567 | Compatible | mc |
Aruba AP577 | Compatible | mc |
Aruba AP555 | Compatible | mc |
Aruba AP635 | Compatible | mc |
Aruba AP655 | Compatible | mc |
Aruba AP615 | Compatible | mc |
Aruba AP734 | Compatible | mc/az |
Aruba AP735 | Compatible | mc/az |
Aruba AP754 | Compatible | mc/az |
Aruba AP755 | Compatible | mc/az |
Téléphones
Fabricant et modèle | Version d'Android |
---|---|
Google Pixel 9 Pro XL | 14+ |
Google Pixel 9 | 14+ |
Google Pixel 9 Pro | 14+ |
Google Pixel 9 Pro XL | 14+ |
Google Pixel 7a | 14+ |
Google Pixel 7 | 14+ |
Google Pixel 8 | 14+ |
Google Pixel 8 Pro | 14+ |
Google Pixel 8a | 14+ |
Samsung SM-S918B | 14+ |
Samsung SM-A515F | 14+ |
Google Pixel 9 Pro | 14+ |
Samsung SM-A546E | 14+ |
Samsung SM-S928B | 14+ |
Samsung SM-A217F | 14+ |
Samsung SM-A715F | 14+ |
Samsung SM-A528B | 14+ |
Samsung SM-A135F | 14+ |
Samsung SM-S911B | 14+ |
Xiaomi 21091116AI | 14+ |
Google Pixel 9 | 14+ |
Samsung SM-A127F | 14+ |
Google Pixel 7 Pro | 14+ |
Samsung SM-A556E | 14+ |
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 Note10+ | 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+ |
Zebra TC52/TC52HC | 10.0+ |
Zebra TC57 | 10.0+ |
Zebra TC72 | 10.0+ |
Zebra TC77 | 10.0+ |
Zebra MC93 | 10.0+ |
Zebra TC8300 | 10.0+ |
Zebra VC8300 | 10.0+ |
Zebra EC30 | 10.0+ |
Zebra ET51 | 10.0+ |
Zebra ET56 | 10.0+ |
Zebra L10 | 10.0+ |
Zebra CC600/CC6000 | 10.0+ |
Zebra MC3300x | 10.0+ |
Zebra MC330x | 10.0+ |
Zebra TC52x | 10.0+ |
Zebra TC57x | 10.0+ |
Zebra EC50 (LAN et HC) | 10.0+ |
Zebra EC55 (WAN) | 10.0+ |
Zebra WT6300 | 10.0+ |
Skorpio X5 | 10.0+ |