Panoramica della ricerca di reti Wi-Fi

Puoi utilizzare le funzionalità di ricerca di reti Wi-Fi fornite dall'API WifiManager per ottenere un elenco di punti di accesso Wi-Fi visibili dal dispositivo.

Procedura di ricerca di reti Wi-Fi

La procedura di scansione prevede tre passaggi:

  1. Registra un listener di trasmissione per SCAN_RESULTS_AVAILABLE_ACTION, che viene chiamato quando le richieste di scansione vengono completate, fornendone lo stato di operazione riuscita. Per i dispositivi con Android 10 (livello API 29) e versioni successive, questa trasmissione verrà inviata per ogni ricerca completa di reti Wi-Fi eseguita sul dispositivo dalla piattaforma o da altre app. Le app possono ascoltare passivamente tutti i completamenti della scansione sul dispositivo utilizzando la trasmissione senza eseguirne la scansione.

  2. Richiedi un'analisi utilizzando WifiManager.startScan(). Assicurati di controllare lo stato restituito del metodo, poiché la chiamata potrebbe non riuscire per uno dei seguenti motivi:

    • Le richieste di scansione potrebbero essere limitate a causa di un numero eccessivo di scansioni in un breve periodo di tempo.
    • Il dispositivo è inattivo e la scansione è disattivata.
    • L'hardware Wi-Fi segnala un errore di ricerca.
  3. Ricevi i risultati dell'analisi utilizzando WifiManager.getScanResults(). I risultati della scansione restituiti sono i risultati aggiornati più di recente, che potrebbero provenire da una scansione precedente se la scansione attuale non è stata completata o non è riuscita. Ciò significa che, se chiami questo metodo prima di ricevere una trasmissione SCAN_RESULTS_AVAILABLE_ACTION, potresti ricevere risultati della scansione meno recenti.

Il seguente codice fornisce un esempio di come implementare questi passaggi:

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 ...
}

Restrizioni

Android 8.0 (livello API 26) ha introdotto limitazioni relative alle autorizzazioni e alla frequenza consentita delle ricerche di reti Wi-Fi.

Per migliorare le prestazioni della rete, la sicurezza e la durata della batteria, Android 9 (livello API 28) ha ridotto i requisiti di autorizzazione e limitato ulteriormente la frequenza delle ricerche di reti Wi-Fi.

Autorizzazioni

Android 8.0 e Android 8.1:

Per una chiamata a WifiManager.getScanResults() riuscita, è necessaria una qualsiasi delle seguenti autorizzazioni:

Se l'app per le chiamate non dispone di nessuna di queste autorizzazioni, la chiamata non riesce con un SecurityException.

In alternativa, sui dispositivi con Android 8.0 (livello API 26) e versioni successive, puoi usare CompanionDeviceManager per eseguire un'analisi dei dispositivi companion nelle vicinanze per conto della tua app senza richiedere l'autorizzazione di accesso alla posizione. Per ulteriori informazioni su questa opzione, consulta Accoppiamento dispositivo associato.

Android 9:

Per una chiamata a WifiManager.startScan() riuscita, sono necessarie tutte le seguenti condizioni:

Android 10 (livello API 29) e versioni successive:

Per una chiamata a WifiManager.startScan() riuscita, sono necessarie tutte le seguenti condizioni:

  • Se la tua app ha come target l'SDK Android 10 (livello API 29) o versioni successive, dispone dell'autorizzazione ACCESS_FINE_LOCATION.
  • Se la tua app ha come target un SDK precedente ad Android 10 (livello API 29), l'app dispone dell'autorizzazione ACCESS_COARSE_LOCATION o ACCESS_FINE_LOCATION.
  • La tua app dispone dell'autorizzazione CHANGE_WIFI_STATE.
  • I servizi di geolocalizzazione sono attivi sul dispositivo (in Impostazioni > Posizione).

Per chiamare WifiManager.getScanResults(), assicurati che siano soddisfatte tutte le seguenti condizioni:

  • Se la tua app ha come target l'SDK Android 10 (livello API 29) o versioni successive, ha l'autorizzazione ACCESS_FINE_LOCATION.
  • Se la tua app ha come target un SDK precedente ad Android 10 (livello API 29), l'app dispone dell'autorizzazione ACCESS_COARSE_LOCATION o ACCESS_FINE_LOCATION.
  • La tua app dispone dell'autorizzazione ACCESS_WIFI_STATE.
  • I servizi di geolocalizzazione sono attivi sul dispositivo (in Impostazioni > Posizione).

Se l'app per le chiamate non soddisfa tutti questi requisiti, la chiamata non riesce con un elemento SecurityException.

Limitazione

Le seguenti limitazioni si applicano alla frequenza delle scansioni utilizzando WifiManager.startScan().

Android 8.0 e Android 8.1:

Ogni app in background può eseguire la scansione una volta ogni 30 minuti.

Android 9:

Ogni app in primo piano può essere analizzata quattro volte in un periodo di 2 minuti. Ciò consente una serie di scansioni in breve tempo.

Tutte le app in background combinate possono essere analizzate una volta ogni 30 minuti.

Android 10 e versioni successive:

Si applicano gli stessi limiti di limitazione di Android 9. È disponibile una nuova opzione per gli sviluppatori che consente di disattivare la limitazione per i test locali (in Opzioni sviluppatore > Networking > Limitazione della scansione del Wi-Fi).