1

I am facing issue related to BLE advertisement scanning. After turning screen off my scanning is working for undefined time then stopping till I turn screen on. BtGatt.ScanManager is logging "Cannot start unfiltered scan in screen-off".

Im providing scan filters like below

class IBeaconScanFilterProvider : BeaconScanFilterProvider {
    override fun get(uuid: UUID): ScanFilter {
        val manufacturerData = ByteBuffer.allocate(23)
        val manufacturerDataMask = ByteBuffer.allocate(23)
        val uuidBytes = getByteArrayFromGuid(uuid.toString())!!

        for (i in 2..17) {
            manufacturerData.put(i, uuidBytes[i - 2])
            manufacturerDataMask.put(i, 0x01)
        }

        return ScanFilter.Builder()
            .setManufacturerData(
                0x004C, //IBeacon
                manufacturerData.array(),
                manufacturerDataMask.array()
            ).build()
    }
}

Then im starting scanning using code below

bluetoothScanner.startScan(
            arrayListOf(beaconScanningContext.filters),
            beaconScanningContext.settings,
            RxBleBroadcastReceiver.newPendingIntent(context)
        )

Every 10 minutes I am resetting scan to avoid the lock that turns off scanning after 10 minutes, added in android 8

Im testing this solution on Android 5.1 (LG G2), Android 7.1.1 (Nexus 6P), Android 8.1 (Pixel XL) and Android 10 (Xiaomi Mi9) and problem occured on Pixel and Mi9

Is there anything that im doing wrong?

drbear
  • 31
  • 2

1 Answers1

2

The approach you describe is sound. You are correct that you need to restart scanning periodically otherwise the scan will be stopped. That change went in with Android 7.0, and it it supposed to be after 30 minutes of scanning (although it is possible some OEMS have customized this.) See here

The restriction on background scans without a scan filter started with Android 8.1 and is enforced slightly differently between OEMs. On Pixel and AOSP phones, any scan filter works, even an empty one. On Samsung a non-empty scan filter is required. See here for more info.

It is unclear why your scan filter doesn't work for you to solve this problem. The filter created by IBeaconScanFilterProvider looks sufficient, but I cannot see from the code shown what is returned by beaconScanningContext.filters. Are you sure this is returning an array of at least one element with a non-empty scan filter? If so, it should work.

davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • yes im 100% sure because when screen is on im scanning only beacons which are described by filter – drbear Jul 13 '20 at 18:35
  • So I use similar code in the Android Beacon Library [here](https://github.com/AltBeacon/android-beacon-library/blob/master/lib/src/main/java/org/altbeacon/beacon/service/scanner/CycledLeScannerForLollipop.java#L180) which absolutely works with the screen off. Not sure what I am doing differently than you. For one thing, I am setting the scan mode to LOW_POWER... I wouldn't think that would make a difference. Also, I note that the mask bytes in your scan filter are set to 0x01 not 0xff which I would expect. But again, I would not think this would make a difference. – davidgyoung Jul 13 '20 at 18:57
  • I tried both of your suggestion, none of them helped – drbear Jul 13 '20 at 21:30
  • You mention several devices. I would focus initial testing on "Android 8.1 (Pixel XL)" as this is a vanilla Android implementation. Only branch out to other OEMs after you see it work on a Google OS image. This helps eliminate the possibility of closed-source OEM customizations interfering with the solution. – davidgyoung Jul 14 '20 at 13:58
  • Based on the approach you suggested I did the update on Pixel XL to Android 10 and application is not scanning with filters I described before. After that i tried to pass empty filters and it works but that's not acceptable. Additionaly I can't log anything from BtGatt.ScanManager on Pixel XL – drbear Jul 16 '20 at 15:00
  • I found out that the problem is with Xiaomi battery optimization, it looks like this mechanism is doing something with the filters. When optimization is turned off, the scan works in the loop - 10s scanning -> empty filters error -> 4s of cooldown – drbear Jul 19 '20 at 11:45