Présentation de la recherche de points d'accès Wi-Fi

Vous pouvez utiliser les fonctionnalités de recherche Wi-Fi fournies par l'API WifiManager pour obtenir la liste des points d'accès Wi-Fi visibles depuis l'appareil.

Processus de recherche Wi-Fi

Le processus d'analyse se déroule en trois étapes:

  1. Enregistrez un écouteur de diffusion pour SCAN_RESULTS_AVAILABLE_ACTION, qui est appelé lorsque les requêtes d'analyse sont terminées, en indiquant leur état de réussite ou d'échec. Pour les appareils équipés d'Android 10 (niveau d'API 29) ou version ultérieure, cette diffusion sera envoyée pour toute recherche Wi-Fi complète effectuée sur l'appareil par la plate-forme ou d'autres applications. Les applications peuvent écouter de manière passive toutes les analyses effectuées sur l'appareil à l'aide de la diffusion, sans émettre la propre analyse.

  2. Demandez une analyse à l'aide de WifiManager.startScan(). Veillez à vérifier l'état renvoyé de la méthode, car l'appel peut échouer pour l'une des raisons suivantes:

    • Les requêtes d'analyse peuvent être limitées en raison d'un trop grand nombre d'analyses sur une courte période.
    • L'appareil est inactif et la recherche est désactivée.
    • Le matériel Wi-Fi signale un échec de la recherche.
  3. Obtenez des résultats d'analyse à l'aide de WifiManager.getScanResults(). Les résultats d'analyse renvoyés sont les résultats les plus récemment mis à jour. Ils peuvent provenir d'une analyse précédente si l'analyse en cours n'a pas abouti ou n'a pas abouti. Cela signifie que vous pouvez obtenir des résultats d'analyse plus anciens si vous appelez cette méthode avant de recevoir une diffusion SCAN_RESULTS_AVAILABLE_ACTION réussie.

Le code suivant fournit un exemple de mise en œuvre de ces étapes:

Kotlin

val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager

val wifiScanReceiver = object : BroadcastReceiver() {

  override fun onReceive(context: Context, intent: Intent) {
    val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)
    if (success) {
      scanSuccess()
    } else {
      scanFailure()
    }
  }
}

val intentFilter = IntentFilter()
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
context.registerReceiver(wifiScanReceiver, intentFilter)

val success = wifiManager.startScan()
if (!success) {
  // scan failure handling
  scanFailure()
}

....

private fun scanSuccess() {
  val results = wifiManager.scanResults
  ... use new scan results ...
}

private fun scanFailure() {
  // handle failure: new scan did NOT succeed
  // consider using old scan results: these are the OLD results!
  val results = wifiManager.scanResults
  ... potentially use older scan results ...
}

Java

WifiManager wifiManager = (WifiManager)
                   context.getSystemService(Context.WIFI_SERVICE);

BroadcastReceiver wifiScanReceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context c, Intent intent) {
    boolean success = intent.getBooleanExtra(
                       WifiManager.EXTRA_RESULTS_UPDATED, false);
    if (success) {
      scanSuccess();
    } else {
      // scan failure handling
      scanFailure();
    }
  }
};

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
context.registerReceiver(wifiScanReceiver, intentFilter);

boolean success = wifiManager.startScan();
if (!success) {
  // scan failure handling
  scanFailure();
}

....

private void scanSuccess() {
  List<ScanResult> results = wifiManager.getScanResults();
  ... use new scan results ...
}

private void scanFailure() {
  // handle failure: new scan did NOT succeed
  // consider using old scan results: these are the OLD results!
  List<ScanResult> results = wifiManager.getScanResults();
  ... potentially use older scan results ...
}

Restrictions

Android 8.0 (niveau d'API 26) a introduit des restrictions concernant les autorisations et la fréquence autorisée des recherches Wi-Fi.

Pour améliorer les performances du réseau, la sécurité et l'autonomie de la batterie, Android 9 (niveau d'API 28) a renforcé les exigences d'autorisation et limité la fréquence des recherches Wi-Fi.

Autorisations

Android 8.0 et Android 8.1:

Un appel réussi à WifiManager.getScanResults() nécessite l'une des autorisations suivantes:

Si l'application appelante ne dispose d'aucune de ces autorisations, l'appel échoue avec une SecurityException.

Sur les appareils équipés d'Android 8.0 (niveau d'API 26) ou version ultérieure, vous pouvez également utiliser CompanionDeviceManager pour analyser les appareils associés à proximité pour le compte de votre application sans avoir besoin de l'autorisation d'accéder à la position. Pour en savoir plus sur cette option, consultez Associer un appareil associé.

Android 9:

Pour que l'appel à WifiManager.startScan() aboutisse, toutes les conditions suivantes doivent être remplies:

Android 10 (niveau d'API 29) ou version ultérieure:

Pour que l'appel à WifiManager.startScan() aboutisse, toutes les conditions suivantes doivent être remplies:

  • Si votre application cible le SDK Android 10 (niveau d'API 29) ou une version ultérieure, elle dispose de l'autorisation ACCESS_FINE_LOCATION.
  • Si votre application cible un SDK inférieur à Android 10 (niveau d'API 29), elle dispose de l'autorisation ACCESS_COARSE_LOCATION ou ACCESS_FINE_LOCATION.
  • Votre application dispose de l'autorisation CHANGE_WIFI_STATE.
  • Les services de localisation sont activés sur l'appareil (sous Settings > Location (Paramètres > Localisation).

Pour appeler WifiManager.getScanResults(), assurez-vous que toutes les conditions suivantes sont remplies:

  • Si votre application cible le SDK Android 10 (niveau d'API 29) ou une version ultérieure, elle dispose de l'autorisation ACCESS_FINE_LOCATION.
  • Si votre application cible un SDK inférieur à Android 10 (niveau d'API 29), elle dispose de l'autorisation ACCESS_COARSE_LOCATION ou ACCESS_FINE_LOCATION.
  • Votre application dispose de l'autorisation ACCESS_WIFI_STATE.
  • Les services de localisation sont activés sur l'appareil (sous Settings > Location (Paramètres > Localisation).

Si l'application appelante ne répond pas à toutes ces exigences, l'appel échoue avec une SecurityException.

Limitation

Les limites suivantes s'appliquent à la fréquence des analyses à l'aide de WifiManager.startScan().

Android 8.0 et Android 8.1:

Chaque application en arrière-plan peut effectuer une analyse une fois toutes les 30 minutes.

Android 9:

Chaque application au premier plan peut être analysée quatre fois par période de deux minutes. Cela permet une rafale d'analyses en peu de temps.

Toutes les applications en arrière-plan réunies peuvent être analysées une fois toutes les 30 minutes.

Android 10 ou version ultérieure:

Les mêmes limites de limitation s'appliquent à Android 9. Une nouvelle option pour les développeurs permet de désactiver la limitation pour les tests locaux (sous Options pour les développeurs > Réseau > Limitation de la recherche Wi-Fi).