AltBeacon / android-beacon-library

Allows Android apps to interact with BLE beacons
Apache License 2.0
2.84k stars 836 forks source link

After 30 min in background, scan stops and starts, but no more beacons are found #1014

Closed hollyhook closed 3 years ago

hollyhook commented 3 years ago

Expected behavior

After the library does restart the scan, beacons should be found again

Actual behavior

The rangeNotifier callback parameter beacons is always empty

Steps to reproduce this behavior

1) request long-running scanning, by adding this to the manifest: <meta-data android:name="longScanForcingEnabled" android:value="true"/> 2) switch on background scanning 3) switch off phone display. All works nicely, beacon distances get delivered as expected 4) gratefully read the docu of this awesome library for the next 30 min 🙂 -> after 30 min, the library stops and restarts scanning, but it can't find any more beacons.

Mobile device model and OS version

Samsung S10, Android 10

Android Beacon Library version

2.17.1

I attach the android log with debug information, where you can see 30 min timeout at 18:57:27.774

I'm happy to provide any additional information, or do support with some debugging.

hollyhook commented 3 years ago

30min.txt

Logfile after 30min background scan

davidgyoung commented 3 years ago

Can you please show your scan setup code?

Can you reproduce this issue on your device with the reference app? https://github.com/AltBeacon/android-beacon-library-reference

I suspect this is not reproducible with that app because I have tested the same with the Galaxy S10 and Android 10. If it is not reproducible with that app, what do you think the difference might be between your app and the reference app?

hollyhook commented 3 years ago

Thanks David. This is how the setup looks like:

    override fun onCreate() { // this is the service onCreate
        super.onCreate()

        beaconManager = BeaconManager.getInstanceForApplication(this)
        beaconManager.setEnableScheduledScanJobs(false)
        beaconManager.isRegionStatePersistenceEnabled = false
        beaconManager.foregroundBetweenScanPeriod = 0
        beaconManager.foregroundScanPeriod = 1100

later when I send the service in background, I call this function:

private fun bindBeacons() {
        beaconManager.beaconParsers.clear()
        for (layout: String in arrayOf(
            IBEACON,
            ALTBEACON, ALTBEACON2,
            EDDYSTONE_TLM, EDDYSTONE_UID, EDDYSTONE_URL,
            EXPOSURE
        )) {
            beaconManager.beaconParsers.add(BeaconParser().setBeaconLayout(layout))
        }
        Log.i(TAG, "binding to beacon manager: $this")
        beaconManager.bind(this)
    }

My first thought is that main difference maybe I have my own dedicated foreground service? However, I will do some more testing, and analyse more deeply what the differences could be.

davidgyoung commented 3 years ago

If you check Settings -> Apps -> Your App -> permissions do you have background location permission granted?

On Sun, Dec 6, 2020 at 2:54 PM hollyhook notifications@github.com wrote:

Thanks David. This is how the setup looks like:

override fun onCreate() { // this is the service onCreate
    super.onCreate()

    beaconManager = BeaconManager.getInstanceForApplication(this)
    beaconManager.setEnableScheduledScanJobs(false)
    beaconManager.isRegionStatePersistenceEnabled = false
    beaconManager.foregroundBetweenScanPeriod = 0
    beaconManager.foregroundScanPeriod = 1100

later when I send the service in background, I call this function:

private fun bindBeacons() { beaconManager.beaconParsers.clear() for (layout: String in arrayOf( IBEACON, ALTBEACON, ALTBEACON2, EDDYSTONE_TLM, EDDYSTONE_UID, EDDYSTONE_URL, EXPOSURE )) { beaconManager.beaconParsers.add(BeaconParser().setBeaconLayout(layout)) } Log.i(TAG, "binding to beacon manager: $this") beaconManager.bind(this) }

My first thought is that main difference maybe I have my own dedicated foreground service? However, I will do some more testing, and analyse more deeply what the differences could be.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/AltBeacon/android-beacon-library/issues/1014#issuecomment-739554195, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAH7C4JGAGN2YVZZNPVNUYTSTPOPXANCNFSM4UPQGIGA .

davidgyoung commented 3 years ago

You might want to check out this answer, too: https://stackoverflow.com/a/57995960/1461050

I notice in your setup code that you have multiple scan filters. Samsung requires scan filters for scans with the screen off, but scan filters are a limited resource, so it is possible you are running out. You might try with just one.

hollyhook commented 3 years ago

This is what I checked so far

Some things are odd. There are two logs:

2020-12-06 18:57:27.774 7043-7043/com.hollyhook.oscHook D/CycledLeScanner: The next scan cycle would go over the Android N max duration.
2020-12-06 18:57:27.774 7043-7043/com.hollyhook.oscHook D/CycledLeScanner: Stopping scan to prevent Android N scan timeout.

I see them in the log of my app, however I cannot find them in them in the logfile of the reference app. They may have escaped me, but I tried it now several times. Which makes me think that maybe the reference app never comes across the critical part of the code? On the other hand, this log is repeatedly created by the reference app I've never seen in my logs.

020-12-07 21:44:26.577 14737-14737/org.altbeacon.beaconreference D/CycledLeScanner: Set a wakeup alarm to go off in 300000 ms: PendingIntent{f712f30: android.os.BinderProxy@eb1e7a9}

It looks like there are definitively differences, just not clear what causes them. My app is at https://bitbucket.org/constanze/oschook2/, the apk is checked in here: https://bitbucket.org/constanze/oschook2/src/master/app/release/app-release.apk

You probably have better things to do, but if you are curious and want to check the logs... It does nice plots of beacon distances, and sends them as OSC :-) It contains the android beacon lib in sources. I had to comment out the download of android-distance.jso, because of GDPR, I guess it would need user consens.

I will try changing the scan filter next.

hollyhook commented 3 years ago

I removed all scan filter but one. The behaviour the same. This is the log taken around 30min after switching the display off. 30min1filter.txt

You can see in 2020-12-08 20:35:49.559, that the scan is stopped to prevent scan time out. Scan is started again at 2020-12-08 20:35:49.578

I think this fails due to the permission problem, as seen here

2020-12-08 20:35:49.594 4769-4885/? E/BluetoothUtils: Permission denial: Need ACCESS_FINE_LOCATION permission to get scan results

This I don't understand. ACCESS_FINE_LOCATION is definitively in my manifest, it wouldn't work the first 30 min, right? After that, no more beacons are delivered to the rangeNotifier callback.

hollyhook commented 3 years ago

I found the issue, the fine location must be granted permanently, which can only be achieved by requesting permission for fine_location and backgroundlocation at the same point in time. ¯_(ツ)/¯ Thanks anyway, now the beacon detection works flawlessly for hours in the background.

davidgyoung commented 3 years ago

Ah, I see. I remember I asked about the permission before, and you noted that location was granted always. So it was COARSE_LOCATION not FINE_LOCATION? Yes, that would be a problem. Android doesn't really make it easy with those two location permission variants.

Glad you solved the problem.