Estoy trabajando en una aplicación que utiliza los escaneos WiFi para funcionar. Utilizo el método startScan()
de la clase WifiManager
y tengo programado un BroadcastReceiver
para que se me notifique cuando el escaneo ha terminado y ya se pueden recoger los resultados.
El código que tengo funciona perfectamente en Android 7 e inferiores, e incluso funciona en Android 8 si configuro el targetSdkVersion
a 25 (Android 7) o inferior.
El problema surge cuando subo el targetSdkVersion
a 26 y ejecuto la aplicación en Android 8 (concretamente en un Nexus 5X), y es que los escaneos WiFi dejan de ser recibidos. Por mucho que yo ejecute startScan()
nunca obtengo resultados. Repito, si bajo el targetSdkVersion
a 25, vuelvo a recibir los resultados sin problemas.
Leyendo la documentación oficial de Android, indica que a partir de Android 8 los esacneos se ejecutarán con mucha menos frecuencia, pero se entiende que deben funcionar de igual manera. Incluso en Android P esta llamada está obsoleta.
Entiendo que en Android P no podré utilizar este método, pero en Android 8 sí, y sin embargo no funciona.
Dejo la documentación de startScan()
por si hiciera falta: Documentación
Alguien sabe el porqué de este comportamiento o a alguien le pasa lo mismo?
EDITO:
Este es el código que inicia los escaneos:
public boolean startScan() {
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
if (!wm.isWifiEnabled()) {
try {
wm.setWifiEnabled(true);
} catch (SecurityException e) {
Log.w(LOG_TAG, "Error enabling wifi", e);
return false;
}
}
boolean started = wm.startScan();
Log.d(LOG_TAG, "Scan started? " + started);
return started;
}
Este es el BroadcastReceiver
que recibe el resultado de los escaneos (y funciona excepto en Android 8 con targetSdkVersion 26+):
public class InOutWifiScanResultsReceiver extends BroadcastReceiver {
private static final String LOG_TAG = "ScanResults";
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent); // Nunca entra aquí con Android 8 y targetSdkVersion 26+
List<ScanResult> results = getWifiResults(context);
Log.d(LOG_TAG, "Received results (" + results.size() + " AP's)");
}
private static List<ScanResult> getWifiResults(Context context) {
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
try {
return wm.getScanResults();
} catch (SecurityException e) {
return new ArrayList<>();
}
}
}
En el Manifest
tengo los siguientes permisos y el BroadcastReceiver
declarado:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<receiver
android:name=".InOutWifiScanResultsReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.net.wifi.SCAN_RESULTS"/>
</intent-filter>
</receiver>
El permiso de localización se pide en runtime
por lo que estoy seguro de que se permite, ya que soy yo el que hace los tests. También me he asegurado de que la localización esté activada (está en máxima precisión (gps + netword)).
El BroadcastReceiver
parece que está declarado porque funciona si el targetSdkVersion es 25 o inferior. También he probado ponerle android:exported="true"
por si tuviera algo que ver, pero parece ser que no.
Agradezco toda ayuda.