Localisation en Wi-Fi: portée avec DAR

Vous pouvez utiliser la fonctionnalité de localisation Wi-Fi fournie par l'API Wi-Fi RTT (Round-Trip-Time) pour mesurer la distance entre les points d'accès Wi-Fi compatibles RTT et les appareils Wi-Fi Aware similaires.

Si vous mesurez la distance jusqu'à trois points d'accès ou plus, vous pouvez utiliser un algorithme de multiplication pour estimer la position de l'appareil qui correspond le mieux à ces mesures. Le résultat est généralement proche de 1 à 2 mètres.

Cette précision vous permet de développer des services de localisation plus précis, tels que la navigation en intérieur, les commandes vocales clarifiées (par exemple, "Allumer cette lumière") et les informations de localisation (par exemple, "Existe-t-il des offres spéciales pour ce produit ?").

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

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

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

Le texte en temps réel 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 équipés d'Android 9, vous devez avoir accès aux données de localisation des points d'accès 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ées par des objets ResponderLocation, y compris la latitude, la longitude et l'altitude. Pour les points d'accès Wi-Fi DAR qui prennent en charge les informations de configuration de la localisation/le rapport civique de localisation (données LCI/LCR), le protocole renvoie un objet ResponderLocation pendant le 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. Votre application peut ainsi trouver les 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.

Exigences

  • Le matériel de l'appareil à l'origine de la requête de mesure des distances doit mettre en œuvre la norme FTM 802.11-2016.
  • L'appareil à l'origine de la requête de mesure des distances doit exécuter Android 9 (niveau d'API 28) ou une version ultérieure.
  • Les services de localisation et la recherche Wi-Fi doivent être activés sur l'appareil qui effectue la requête de mesure (sous Paramètres > Localisation).
  • Si l'application qui envoie la requête de mesure cible Android 13 (niveau d'API 33) ou une 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'autorisation ACCESS_FINE_LOCATION à 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 en arrière-plan.
  • Le point d'accès doit implémenter la norme FTM IEEE 802.11-2016.

Configurer

Pour configurer votre application afin qu'elle utilise le texte en temps réel via le 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 dangereuses. Vous devez donc les demander au moment de l'exécution chaque fois que l'utilisateur souhaite effectuer une analyse DAR. Votre application doit demander l'autorisation de l'utilisateur si celle-ci n'a pas déjà été accordée. Pour en savoir plus sur les autorisations d'exécution, consultez la section Demander des autorisations d'applications.

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

Pour vérifier si l'appareil est compatible avec le Wi-Fi DAR, utilisez l'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 Wi-Fi est disponible

Le Wi-Fi RTT peut exister sur l'appareil, mais il est possible qu'il ne soit pas disponible actuellement, car l'utilisateur a désactivé le Wi-Fi. En fonction de leurs capacités matérielles et de micrologiciel, certains appareils peuvent ne pas être compatibles avec le Wi-Fi RTT si SoftAP ou le partage de connexion sont utilisés. Pour vérifier si le RTT Wi-Fi est actuellement 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, 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.

Par 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 demande de portée

Une requête de portée (RangingRequest) est créée en spécifiant une liste de points d'accès ou de pairs Wi-Fi Aware auxquels une plage est demandée. Plusieurs points d'accès ou pairs Wi-Fi Aware peuvent être spécifiés dans une seule requête de mesure des distances. Les distances par rapport à 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) pour ajouter plusieurs points d'accès dans un lot.

De même, une requête de mesure peut ajouter un pair Wi-Fi Aware à l'aide de son adresse MAC ou de son PeerHandle, à l'aide des méthodes addWifiAwarePeer(MacAddress peer) et addWifiAwarePeer(PeerHandle), respectivement. Pour en savoir plus sur la recherche d'appairages Wi-Fi Aware, consultez la documentation Wi-Fi Aware.

Plage de requêtes

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

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

  • Si l'ensemble de l'opération de portée échoue, le rappel onRangingFailure est déclenché avec un code d'état décrit dans la section RangingResultCallback. Un tel échec peut se produire si le service ne peut pas exécuter une opération de mesure des distances à ce moment-là, par exemple parce que le Wi-Fi est désactivé, parce que l'application a demandé trop d'opérations de portée et qu'elle est limitée, ou en raison d'un problème d'autorisation.
  • Une fois l'opération de sélection de plages 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 des distances peut s'effectuer, mais que chaque résultat peut toujours indiquer un échec de cette mesure spécifique.

Interpréter les résultats d'une répartition des plages

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

1. Identifier la demande

Identifiez la requête en fonction des informations fournies lors de la création de la RangingRequest : le plus souvent, il s'agit d'une adresse MAC fournie dans le ScanResult qui identifie un point d'accès. Vous pouvez obtenir l'adresse MAC à partir du résultat de la mesure de distance à l'aide de la méthode getMacAddress().

La liste des résultats de mesure des distances peut s'afficher dans un ordre différent de celui des pairs (points d'accès) spécifiés dans la requête de mesure. 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 échoue et génère une exception IllegalStateException .

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

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

Appareils Android compatibles avec le Wi-Fi-RTT

Les tableaux ci-dessous répertorient certains téléphones, points d'accès et appareils de point de vente, d'entreposage et de distribution compatibles avec le Wi-Fi-RTT. Elles sont loin d'être complètes. Nous vous invitons à nous contacter pour lister ici vos produits compatibles avec le texte en temps réel.

Points d'accès

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

Téléphones

Fabricant et modèle Version d'Android
Pixel 6 9 et plus
Pixel 6 Pro 9 et plus
Pixel 5 9 et plus
Pixel 5a 9 et plus
Pixel 5a (5G) 9 et plus
Xiaomi Mi 10 Pro 9 et plus
Xiaomi Mi 10 9 et plus
Xiaomi Redmi Mi 9T Pro 9 et plus
Xiaomi Mi 9T 9 et plus
Xiaomi Mi 9 9 et plus
Xiaomi Mi Note 10 9 et plus
Xiaomi Mi Note 10 Lite 9 et plus
Xiaomi Redmi Note 9S 9 et plus
Xiaomi Redmi Note 9 Pro 9 et plus
Xiaomi Redmi Note 8T 9 et plus
Xiaomi Redmi Note 8 9 et plus
Xiaomi Redmi K30 Pro 9 et plus
Xiaomi Redmi K20 Pro 9 et plus
Xiaomi Redmi K20 9 et plus
Xiaomi Redmi Note 5 Pro 9 et plus
Xiaomi Mi CC9 Pro 9 et plus
LG G8X ThinQ 9 et plus
LG V50S ThinQ 9 et plus
LG V60 ThinQ 9 et plus
LG V30 9 et plus
Samsung Galaxy Note 10+ 5G 9 et plus
Samsung Galaxy S20+ 5G 9 et plus
Samsung Galaxy S20+ 9 et plus
Samsung Galaxy S20 5G 9 et plus
Samsung Galaxy S20 Ultra 5G 9 et plus
Samsung Galaxy S20 9 et plus
Samsung Galaxy Note 10+ 9 et plus
Samsung Galaxy Note 10 5G 9 et plus
Samsung Galaxy Note 10 9 et plus
Samsung A9 Pro 9 et plus
Google Pixel 4 XL 9 et plus
Google Pixel 4 9 et plus
Google Pixel 4a 9 et plus
Google Pixel 3 XL 9 et plus
Google Pixel 3 9 et plus
Google Pixel 3a XL 9 et plus
Google Pixel 3a 9 et plus
Google Pixel 2 XL 9 et plus
Google Pixel 2 9 et plus
Google Pixel 1 XL 9 et plus
Google Pixel 1 9 et plus
Poco X2 9 et plus
Sharp Aquos R3 SH-04L 9 et plus

Appareils de centre de vente, d'entreposage et de distribution

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