Puoi utilizzare le funzionalità di ricerca delle reti Wi-Fi fornite dall'API WifiManager per ottenere un elenco dei punti di accesso Wi-Fi visibili dal dispositivo.
Procedura di ricerca di reti Wi-Fi
La procedura di scansione è composta da tre passaggi:
Registra un listener di trasmissione per
SCAN_RESULTS_AVAILABLE_ACTION
, che viene chiamato quando vengono completate le richieste di scansione e indica lo stato di operazione riuscita/non riuscita. Per i dispositivi con Android 10 (livello API 29) e versioni successive, questa trasmissione verrà inviata per qualsiasi 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 dover eseguire una scansione personale.Richiedi una scansione 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 troppe analisi in un breve periodo di tempo.
- Il dispositivo è inattivo e la scansione è disattivata.
- L'hardware Wi-Fi segnala un errore di ricerca.
Ottieni i risultati dell'analisi utilizzando
WifiManager.getScanResults()
. I risultati della scansione restituiti sono i risultati aggiornati più di recente, che possono provenire da un'analisi precedente se l'analisi corrente non è stata completata o riuscita. Ciò significa che potresti ottenere risultati dell'analisi meno recenti se chiami questo metodo prima di ricevere una trasmissione diSCAN_RESULTS_AVAILABLE_ACTION
riuscita.
Il codice riportato di seguito 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 scansioni di reti Wi-Fi.
Per migliorare le prestazioni della rete, la sicurezza e la durata della batteria, Android 9 (livello API 28) ha intensificato i requisiti di autorizzazione e limitato ulteriormente la frequenza delle scansioni di reti Wi-Fi.
Autorizzazioni
Android 8.0 e Android 8.1:
Per completare una chiamata a
WifiManager.getScanResults()
è necessaria una 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 utilizzare CompanionDeviceManager
per eseguire un'analisi dei dispositivi associati nelle vicinanze per conto della tua app senza richiedere l'autorizzazione di accesso alla posizione. Per ulteriori informazioni su questa opzione, consulta
Accoppiamento
di dispositivi associati.
Android 9:
Per completare una chiamata a WifiManager.startScan()
, sono necessarie tutte le seguenti condizioni:
- La tua app dispone dell'autorizzazione
ACCESS_FINE_LOCATION
oACCESS_COARSE_LOCATION
. - La tua app dispone dell'autorizzazione
CHANGE_WIFI_STATE
. - I servizi di geolocalizzazione siano attivi sul dispositivo (in Impostazioni > Posizione).
Android 10 (livello API 29) e versioni successive:
Per completare una chiamata a WifiManager.startScan()
, sono necessarie tutte le seguenti condizioni:
- Se la tua app ha come target l'SDK Android 10 (livello API 29) o versioni successive, l'app dispone
dell'autorizzazione
ACCESS_FINE_LOCATION
. - Se la tua app ha come target l'SDK precedente ad Android 10 (livello API 29), l'app
ha l'autorizzazione
ACCESS_COARSE_LOCATION
oACCESS_FINE_LOCATION
. - La tua app dispone dell'autorizzazione
CHANGE_WIFI_STATE
. - I servizi di geolocalizzazione siano attivi sul dispositivo (in Impostazioni > Posizione).
Per chiamare correttamente
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, l'app
dispone dell'autorizzazione
ACCESS_FINE_LOCATION
. - Se la tua app ha come target l'SDK precedente ad Android 10 (livello API 29), l'app
dispone dell'autorizzazione
ACCESS_COARSE_LOCATION
oACCESS_FINE_LOCATION
. - La tua app dispone dell'autorizzazione
ACCESS_WIFI_STATE
. - I servizi di geolocalizzazione siano attivi sul dispositivo (in Impostazioni > Posizione).
Se l'app per le chiamate non soddisfa tutti questi requisiti, la chiamata non riesce con
un SecurityException
.
Limitazione
Le seguenti limitazioni si applicano alla frequenza delle analisi con WifiManager.startScan()
.
Android 8.0 e Android 8.1:
Ogni app in background può eseguire la scansione una volta in un periodo di 30 minuti.
Android 9:
Ogni app in primo piano può eseguire quattro scansioni in un periodo di 2 minuti. Ciò consente un burst di scansioni in breve tempo.
Tutte le app in background combinate possono eseguire la scansione una volta in un periodo di 30 minuti.
Android 10 e versioni successive:
Si applicano gli stessi limiti di limitazione di Android 9. È disponibile una nuova opzione sviluppatore per disattivare la limitazione per i test locali (in Opzioni sviluppatore > Networking > Limitazione della ricerca di reti Wi-Fi).