ReactiveWiFi icon indicating copy to clipboard operation
ReactiveWiFi copied to clipboard

Too much callbacks when observing "observeWifiAccessPoints"

Open lemberh opened this issue 7 years ago • 7 comments

I'm using ReactiveWifiLocal.observeWifiAccessPoints(context) everything works well except that I'm receiving too much events, and it is causing high cpu load, lags and battery drain. I can handle it partially by using .throttleFirst(SAMPLING_TIME, TimeUnit.SECONDS) but anyway the library it-selves receives callbacks in BroadcastReceiver

I suggest to do something like

 public static Observable<List<ScanResult>> observeWifiAccessPoints(final Context context,final int scanInterval) {
     final WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
     wifiManager.startScan(); // without starting scan, we may never receive any scan results

    final IntentFilter filter = new IntentFilter();
    filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
    filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);

    return Observable.create(new Observable.OnSubscribe<List<ScanResult>>() {
        @Override
        public void call(final Subscriber<? super List<ScanResult>> subscriber) {
            final BroadcastReceiver receiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {

                    AndroidSchedulers.mainThread().createWorker().schedule(new Action0() {
                        @Override
                        public void call() {
                            wifiManager.startScan(); // we need to start scan again to get fresh results ASAP
                        }
                    }, scanInterval, TimeUnit.SECONDS);

                    subscriber.onNext(wifiManager.getScanResults());
                }
            };

            context.registerReceiver(receiver, filter);

            subscriber.add(unsubscribeInUiThread(new Action0() {
                @Override
                public void call() {
                    context.unregisterReceiver(receiver);
                }
            }));
        }
    });
}

This is how often I get updates:

10-30 13:31:29.051 28695-28695/br.com.oitchau D/WiFiListener: mark as available 8 items 10-30 13:31:29.118 28695-28695/br.com.oitchau D/WiFiListener: mark as available 8 items 10-30 13:31:29.159 28695-28695/br.com.oitchau D/WiFiListener: mark as available 8 items 10-30 13:31:29.199 28695-28695/br.com.oitchau D/WiFiListener: mark as available 8 items 10-30 13:31:29.304 28695-28695/br.com.oitchau D/WiFiListener: mark as available 8 items 10-30 13:31:29.358 28695-28695/br.com.oitchau D/WiFiListener: mark as available 8 items 10-30 13:31:29.396 28695-28695/br.com.oitchau D/WiFiListener: mark as available 8 items 10-30 13:31:29.426 28695-28695/br.com.oitchau D/WiFiListener: mark as available 8 items 10-30 13:31:29.465 28695-28695/br.com.oitchau D/WiFiListener: mark as available 8 items 10-30 13:31:29.499 28695-28695/br.com.oitchau D/WiFiListener: mark as available 8 items 10-30 13:31:29.538 28695-28695/br.com.oitchau D/WiFiListener: mark as available 8 items 10-30 13:31:29.580 28695-28695/br.com.oitchau D/WiFiListener: mark as available 8 items 10-30 13:31:29.626 28695-28695/br.com.oitchau D/WiFiListener: mark as available 8 items

lemberh avatar Oct 30 '17 12:10 lemberh

Hi,

Thanks for reporting this issue. I'll take a closer look on that. Generally, we cannot really control the time, when new set of the access points will be delivered. It depends on Android and a specific device. I'll analyze this issue in the free time and try to figure out if it's possible to improve it. Please note, even if we add scan interval, delivery of the results is a separate thing and we never know, when we receive them even when the scan will be delayed.

Regards, Piotr

pwittchen avatar Oct 30 '17 14:10 pwittchen

Thanks for quick reply, I tested above mentioned solution, looks like when you don't call wifiManager.startScan(); after receiving data in broadcast receiver the system wont send you updates

lemberh avatar Oct 30 '17 16:10 lemberh

That's correct. I know it's not the best solution, but it's the only solution I know, which allows to receive updates about access points continuously. If you call wifiManger.startScan(); once, you'll get results only once.

You can build another observable on top of that for your specific use case. E.g. you can store unique APs somewhere (in the memory, database, shared prefs, etc.) and then subscribe the new observable for data changes so you won't be flooded by incoming scan results all the time.

pwittchen avatar Oct 30 '17 17:10 pwittchen

var disposable: Disposable? = null
 disposable = ReactiveWifi.observeWifiAccessPoints(applicationContext)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({ scanResults ->

                   // logic
                    disposable?.dispose()
                })

paulomcnally avatar Feb 16 '18 20:02 paulomcnally

I'm using ReactiveWifi.observeWifiAccessPoints(context) to fetch the list of access points in my android app. Everything works fine when device is in unlock mode. If device goes to lock mode, access points list do not update and it gives previously captured list i.e., captured in unlock mode. When i come back from lock mode to unlock mode, app freezes for few seconds and after few seconds it get resumes & works normally. I need help to get list of access points when my phone is in lock mode. I've added screenshot of logs below. reactwifi

akashgowda0110 avatar Jul 05 '18 10:07 akashgowda0110

Hi @akashgowda0110. I was AFK. I'm not sure about behavior and monitoring capabilities in "lock mode". Maybe Android OS is blocking scanning in this mode due to performance or energy saving reasons. It's reasonable for me. Have you put scanning code in the Service? IMO in the Activity it shouldn't work in "locked mode" by design. Moreover, the issue mentioned by you is different than this one.

pwittchen avatar Jul 09 '18 11:07 pwittchen

Thank you. As you told, Android OS which was blocking for energy saving reason. Works fine with Naugat and below versions of android. Oreo version of android having problem with this.

akashgowda0110 avatar Jul 10 '18 04:07 akashgowda0110