Puoi utilizzare le funzionalità di scansione 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
Il processo di scansione prevede tre passaggi:
Registra un listener di trasmissione per
SCAN_RESULTS_AVAILABLE_ACTION
, che viene chiamato al termine delle richieste di scansione, fornendo il relativo stato di riuscita/errore. Per i dispositivi con Android 10 (livello API 29) e versioni successive, questa trasmissione verrà inviata per qualsiasi scansione Wi-Fi completa 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 eseguire una propria scansione.Richiedi una scansione utilizzando
WifiManager.startScan()
. Assicurati di controllare lo stato di ritorno 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 scansione.
Ottenere i risultati della scansione utilizzando
WifiManager.getScanResults()
. I risultati della scansione restituiti sono quelli aggiornati più di recente, che potrebbero provenire da una scansione precedente se quella attuale non è stata completata o non è andata a buon fine. Ciò significa che potresti ottenere risultati di scansione precedenti se chiami questo metodo prima di ricevere una trasmissioneSCAN_RESULTS_AVAILABLE_ACTION
andata a buon fine.
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 scansioni Wi-Fi.
Per migliorare le prestazioni di rete, la sicurezza e la durata della batteria, Android 9 (livello API 28) ha reso più rigorosi i requisiti delle autorizzazioni e ha ulteriormente limitato la frequenza delle scansioni Wi-Fi.
Autorizzazioni
Android 8.0 e Android 8.1:
Una chiamata riuscita a
WifiManager.getScanResults()
richiede una qualsiasi delle seguenti autorizzazioni:
Se l'app di chiamata non dispone di nessuna di queste autorizzazioni, la chiamata non va a buon fine e viene visualizzato un
SecurityException
.
In alternativa, sui dispositivi con Android 8.0 (livello API 26) e versioni successive, puoi
utilizzare
CompanionDeviceManager
per eseguire una scansione dei dispositivi complementari nelle vicinanze per conto della tua app senza
richiedere l'autorizzazione di accesso alla posizione. Per saperne di più su questa opzione, consulta
Accoppiamento del dispositivo
complementare.
Android 9:
Una chiamata riuscita a
WifiManager.startScan()
richiede che siano soddisfatte tutte le seguenti condizioni:
- La tua app ha l'autorizzazione
ACCESS_FINE_LOCATION
oACCESS_COARSE_LOCATION
. - La tua app ha l'autorizzazione
CHANGE_WIFI_STATE
. - I servizi di localizzazione sono attivati sul dispositivo (in Impostazioni > Posizione).
Android 10 (livello API 29) e versioni successive:
Una chiamata riuscita a
WifiManager.startScan()
richiede 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), la tua app
dispone dell'autorizzazione
ACCESS_COARSE_LOCATION
oACCESS_FINE_LOCATION
. - La tua app ha l'autorizzazione
CHANGE_WIFI_STATE
. - I servizi di localizzazione sono attivi sul dispositivo (in Impostazioni > Posizione).
Per chiamare correttamente
WifiManager.getScanResults()
,
assicurati che tutte le seguenti condizioni siano soddisfatte:
- 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), la tua app
dispone dell'autorizzazione
ACCESS_COARSE_LOCATION
oACCESS_FINE_LOCATION
. - La tua app ha l'autorizzazione
ACCESS_WIFI_STATE
. - I servizi di localizzazione sono attivi sul dispositivo (in Impostazioni > Posizione).
Se l'app di chiamata non soddisfa tutti questi requisiti, la chiamata non va a buon fine e viene visualizzato un
SecurityException
.
Limitazione
Le seguenti limitazioni si applicano alla frequenza delle scansioni che utilizzano
WifiManager.startScan()
.
Android 8.0 e Android 8.1:
Ogni app in background può eseguire una scansione una volta in un periodo di 30 minuti.
Android 9:
Ogni app in primo piano può eseguire la scansione quattro volte in un periodo di 2 minuti. Ciò consente una raffica di scansioni in un breve periodo di 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 throttling di Android 9. È disponibile una nuova opzione sviluppatore per disattivare la limitazione per i test locali (in Opzioni sviluppatore > Rete > Limitazione della ricerca di reti Wi-Fi).