WiFi scans are not received when running startScan () on Android 8 with targetSdkVersion 26+

3

I'm working on an application that uses WiFi scans to work. I use the method startScan() of the class WifiManager and I have programmed a BroadcastReceiver to be notified when the scan has finished and the results can now be collected.

The code I have works perfectly on Android 7 and below, and even works on Android 8 if I set the% co_of% to 25 (Android 7) or lower.

The problem arises when I upload the targetSdkVersion to 26 and run the application on Android 8 (specifically on a Nexus 5X), and that WiFi scans are no longer received. As much as I execute targetSdkVersion I never get results. I repeat, if under% co_of% to 25, I will receive the results again without problems.

Reading the official documentation of Android, indicates that from Android 8 the esacneos will run much less frequently, but it is understood that they should work in the same way. Even on Android P this call is obsolete.

I understand that in Android P I will not be able to use this method, but in Android 8 yes, and yet it does not work.

I leave the startScan() documentation in case needed: Documentation

Does anyone know the reason for this behavior or does the same thing happen to someone?

EDIT:

This is the code that starts the scans :

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

This is the targetSdkVersion that receives the result of the scans (and it works except in Android 8 with 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<>();
      }
   }
}

In the startScan() I have the following permissions and the BroadcastReceiver declared:

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

The location permission is requested in Manifest , so I am sure that it is allowed, since I am the one who does the tests. I have also made sure that the location is activated (it is in maximum precision (gps + netword)).

The BroadcastReceiver seems to be declared because it works if the targetSdkVersion is 25 or less. I have also tried to put runtime in case it had something to do, but it seems that it does not.

I appreciate any help.

    
asked by Marc Estrada 21.05.2018 в 14:02
source

1 answer

3

In Android 8 or higher the implicit BroadcastRecivers declared via Manifest do not send or receive information for reasons of performance and battery consumption, it is an optimization introduced in Android 8 and that tries to limit the jobs that are executed in background .

There are some exceptions to this ( excecptions ), but the action android.net.wifi.SCAN_RESULTS unfortunately it is not one of those exceptions, so Android 8+ can not register android.net.wifi.SCAN_RESULTS via Manifest since nothing will be received.

This happens when we use targetSdkVersion = 26 (Android 8 Oreo) or higher, but if we declare in Gradle a targetSdkVersion = 25 or less the optimization would not apply and the app would work as expected until today.

To make this functionality return the expected results in Android 8 with targetSdkVersion 26+ you must register the action in the context of the application.

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.wifi.SCAN_RESULTS");
context.registerReceiver(new InOutWifiScanResultsReceiver(), intentFilter);

The only thing is that you have to be careful with this, since it only works when the app is in the foreground and not when it is stopped.

Greetings,

    
answered by 04.06.2018 / 11:42
source