Puedes utilizar las funciones de búsqueda de Wi-Fi proporcionadas por la API de WifiManager para obtener una lista de puntos de acceso Wi-Fi visibles desde el dispositivo.
Proceso de búsqueda de Wi-Fi
El proceso de búsqueda consta de tres pasos:
Registrar un receptor de transmisiones para
SCAN_RESULTS_AVAILABLE_ACTION
, al que se llama cuando se completan las solicitudes de búsqueda, indicando su estado de éxito o fracaso. En el caso de los dispositivos con Android 10 (API nivel 29) y versiones posteriores, se enviará esta transmisión para cualquier búsqueda de Wi-Fi completa que la plataforma u otras apps realicen en el dispositivo. Las apps pueden recibir de forma pasiva todas las finalizaciones de búsqueda en el dispositivo utilizando la transmisión sin emitir una búsqueda propia.Solicitar una búsqueda mediante
WifiManager.startScan()
. Asegúrate de comprobar el estado del método, ya que la llamada puede fallar debido a cualquiera de las siguientes razones:- Es posible que se limiten las solicitudes de búsqueda debido a demasiadas búsquedas en poco tiempo.
- El dispositivo está inactivo y la búsqueda está inhabilitada.
- El hardware Wi-Fi informa acerca de un error de búsqueda.
Obtener resultados de la búsqueda con
WifiManager.getScanResults()
. Los resultados de la búsqueda que se muestran son los actualizados más recientemente, que pueden ser de una búsqueda anterior si la actual no se completó o no se realizó correctamente. Esto significa que puedes obtener resultados de búsqueda más antiguos si llamas a este método antes de recibir una transmisión deSCAN_RESULTS_AVAILABLE_ACTION
que se realizó correctamente.
El siguiente código proporciona un ejemplo de cómo implementar estos pasos:
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 ... }
Restricciones
Android 8.0 (API nivel 26) introdujo restricciones con respecto a los permisos y la frecuencia permitida de las búsquedas de Wi-Fi.
Para mejorar el rendimiento de la red, la seguridad y la duración de la batería, Android 9 (API nivel 28) reforzó los requisitos de permisos y limitó aún más la frecuencia de las búsquedas de Wi-Fi.
Permisos
Android 8.0 y Android 8.1:
Para que una llamada a WifiManager.getScanResults()
se realice correctamente, se requiere cualquiera de los siguientes permisos:
Si la app de llamada no tiene ninguno de estos permisos, la llamada falla con una SecurityException
.
Como alternativa, en los dispositivos con Android 8.0 (API nivel 26) y versiones posteriores, puedes usar el CompanionDeviceManager
para realizar una búsqueda de los dispositivos complementarios cercanos en nombre de tu app sin solicitar permiso de ubicación. Para obtener más información sobre esta opción, consulta Vinculación de dispositivos complementarios.
Android 9:
Una llamada que se realiza correctamente a WifiManager.startScan()
requiere que se cumplan todas estas condiciones:
- Tu app tiene el permiso
ACCESS_FINE_LOCATION
oACCESS_COARSE_LOCATION
. - Tu app tiene el permiso
CHANGE_WIFI_STATE
. - Los servicios de ubicación están habilitados en el dispositivo (en Configuración > Ubicación).
Android 10 (API nivel 29) y versiones posteriores:
Una llamada que se realiza correctamente a WifiManager.startScan()
requiere que se cumplan todas estas condiciones:
- Si tu app se orienta al SDK de Android 10 (API nivel 29) o versiones posteriores, tiene el permiso
ACCESS_FINE_LOCATION
. - Si tu app se orienta a un SDK inferior a Android 10 (API nivel 29), tiene el permiso
ACCESS_COARSE_LOCATION
oACCESS_FINE_LOCATION
. - Tu app tiene el permiso
CHANGE_WIFI_STATE
. - Los servicios de ubicación están habilitados en el dispositivo (en Configuración > Ubicación).
Para llamar correctamente a WifiManager.getScanResults()
, asegúrate de que se cumplan todas estas condiciones:
- Si tu app se orienta al SDK de Android 10 (API nivel 29) o versiones posteriores, tiene el permiso
ACCESS_FINE_LOCATION
. - Si tu app se orienta a un SDK inferior a Android 10 (API nivel 29), tiene el permiso
ACCESS_COARSE_LOCATION
oACCESS_FINE_LOCATION
. - Tu app tiene el permiso
ACCESS_WIFI_STATE
. - Los servicios de ubicación están habilitados en el dispositivo (en Configuración > Ubicación).
Si la app que realiza la llamada no cumple con todos estos requisitos, la llamada falla con una SecurityException
.
Limitación
Se aplican las siguientes limitaciones a la frecuencia de búsquedas mediante WifiManager.startScan()
.
Android 8.0 y Android 8.1:
Cada app en segundo plano puede realizar una búsqueda en un período de 30 minutos.
Android 9:
Cada app en primer plano puede realizar cuatro búsquedas en un período de 2 minutos. Esto permite un pico de actividad de búsquedas en poco tiempo.
Todas las apps en segundo plano combinadas pueden realizar una búsqueda en un período de 30 minutos.
Android 10 y versiones posteriores:
Se aplican los mismos límites de restricción que para Android 9. Existe una nueva opción para desarrolladores que permite desactivar el control para pruebas locales (en Opciones para desarrolladores > Redes > Limitación de búsqueda de Wi-Fi).