NordicSemiconductor / Android-BLE-Library

A library that makes working with Bluetooth LE on Android a pleasure. Seriously.
BSD 3-Clause "New" or "Revised" License
1.99k stars 414 forks source link

Android is moving bluetooth scan client to opportunistic more than it should #512

Closed rickymohk closed 11 months ago

rickymohk commented 12 months ago

I am developing an Android app to continuously scan for BLE devices.

First I encounter this problem https://stackoverflow.com/questions/43833904/android-bluetooth-le-scanner-stops-after-a-time

So I implement a timer to restart the scan at regular interval. But I still find it happening sometimes. When I dig into the Android source code, I found a subtle difference in the latest version of ScanManager.java.

In Android 7 :

...
                    if (!mScanNative.isFirstMatchScanClient(client)) {
                        Message msg = mHandler.obtainMessage(MSG_SCAN_TIMEOUT);
                        msg.obj = client;
                        // Only one timeout message should exist at any time
                        mHandler.removeMessages(SCAN_TIMEOUT_MS);
                        mHandler.sendMessageDelayed(msg, SCAN_TIMEOUT_MS);
                    }
...

In latest version:

...
                    if (!mScanNative.isExemptFromScanDowngrade(client)) {
                        Message msg = obtainMessage(MSG_SCAN_TIMEOUT);
                        msg.obj = client;
                        // Only one timeout message should exist at any time
                        sendMessageDelayed(msg, AppScanStats.getScanTimeoutMillis());
                    }
...

The removeMessage call is removed inside handleStartScan. The MSG_SCAN_TIMEOUT message can now only be removed in handleStopScan.

I suspect when I kill my app, I cannot call stopScan since my app is killed. I also lost the reference to my scanCallback so there is no way for me to call stopScan in new app session. Hence there is no way to cancel the MSG_SCAN_TIMEOUT previously set up. When I start my app again and obtain the BLE scanner with the same scannerId, the persisting MSG_SCAN_TIMEOUT will move my newly started scan to opportunistic. Am I correct about this? If this is the case, is this a bug in Android OS and is there any workaround I can do?

philips77 commented 11 months ago

Scanning is not in scope of this library. I recommend asking this question on StackOverflow.

As a quick answer I suggest using scan with a PendingIntent. This is the desired way to handle continuous scan on Android 8+. Here is the API.

rickymohk commented 11 months ago

Oops, sorry, I mixed it up. Should have asked this in Android-Scanner-Compat-Library