Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android O 8.1 - Avoid 15 minute background limit #642

Closed
jonface opened this issue Feb 5, 2018 · 7 comments
Closed

Android O 8.1 - Avoid 15 minute background limit #642

jonface opened this issue Feb 5, 2018 · 7 comments

Comments

@jonface
Copy link

jonface commented Feb 5, 2018

Expected behavior

With the screen off and no external power, beacon scanning can run continuously. I am filtering for a single iBeacon UUID. After 15 minutes of no beacon activity, I start emitting the iBeacon and expect the phone to detect it.

Actual behavior

Beacon scanning stops after approx 15 minutes. Have tried running the scanning as a foreground service but this still seems to stop.

Steps to reproduce this behavior

Scan for beacons with the screen off and the phone not powered externally. Wait for approx 15 minutes with no beacon activity and then start emitting beacons. Phone application should not respond.

Mobile device model and OS version

Google Pixel 2 8.1.0

Android Beacon Library version

2.12.4-android8_1

I don't have much/any android experience, but I've read,
http://www.davidgyoungtech.com/2017/08/07/beacon-detection-with-android-8 . Now assuming battery usage doesn't matter, is there anyway around this, such that beacon detection is near instant, as it is when the screen is on? The pre-release version 2.12.4-android8_1 allowed scanning to work with the screen off which was great, I'm just wondering if anything else can be done to allow continuous scanning with the screen off, greater than 15 minutes?

Thanks

@jonface jonface changed the title Android O 8.1 Android O 8.1 - Avoid 15 minute background limit Feb 5, 2018
@breon
Copy link

breon commented Feb 5, 2018

I had only tested while viewing logcat over USB. I can confirm that our ranging service stops around 15 minutes (monitored over wifi). See attached.
android8.1_log.txt

@jonface
Copy link
Author

jonface commented Feb 8, 2018

So to confirm, Android 8.1, continuous scanning and reacting to advertisements within a couple of seconds reliably is not possible by any means? Excluding rooting / modifying the OS.

@davidgyoung
Copy link
Member

davidgyoung commented Feb 8, 2018

I think there are three issues at play here, and I am unsure which one is causing the trouble:

  1. On Android 8.1 scans are blocked if you start them with the screen off unless there is a scan filter active. This was reported in Android 8.1 and Ranging #633 and there is a fix in Allow scans with screen off on Android 8.1 #637, which is in a test release here. I assume from the description of this issue that this issue was found using that test release.

  2. On Android 7+, continual scans are blocked if they keep going for more than 30 minutes. This is reported in Android 7 scanning stops after 30 minutes #526 and a fix was put into Allow forcing long scans on Android N #529. However, in order to activate that fix, you need to add a special entry into the manifest as it overrides Android's default power saving behavior. See Allow forcing long scans on Android N #529 for details.

  3. On Android 8+ the JobScheduler is used by default to perform scans when the app is not in the foreground. These scan jobs are schedule every 15 minutes when the app is in the background, and Android does not let you schedule Jobs more frequently than that, so scans will start approximately every 15 minutes and last for the configured scanPeriod (but limited to a max of 10 minutes by the operating system).

Based on the report, I am unsure if the behavior you witness is caused by either item 2 or item 3 above. It sounds like you are saying that after 15 minutes you never see ranging results again. Is this true, or do you only see them after a delay as described in item 3?

Based on default configuration, this library will react to a new beacon detection in the background beacons very quickly (within a few seconds) because it uses hardware filters and scans based on Intents that are not blocked in the background. This, however, will only work for new detections of beacons when previously no beacons had been detected. If you continually want to detect beacons in the vicinity, then you are limited to about 10 minutes of ranging every approximately 15 minutes. However, if you do not use BackgroundPowerSaver or you change the default scan settings, it may defeat some of this functionality, as the filtered Intent-based scans only work if you are in a between scan period in the background. If you change the scan settings to be more frequent and then the scans get blocked by the operating system, then you may be shooting yourself in the foot.

IMPORTANT NOTE: If you are running your own service, understand that Android 8 block services running longer than about 10 minutes if the app is in the background (unless they are a foreground service that shows an icon in the top bar while they are running.) This has nothing to do with the library, but is an Android 8 restriction on your custom service. (@breon is this possibly your issue?)

@jonface
Copy link
Author

jonface commented Feb 13, 2018

Thanks for your reply @davidgyoung . This is what I've tried,

Using the test build, when the screen is off, with a filtered scan, scanning continues for a time period, previously it just stopped with the screen off. I added to my application manifest, the xml from #529, not sure if this makes much difference though.

As you said, scanning does stop after a period of time. Generally it does start again, strangely not all the time. The below log was generated with dumpsys deviceidle force-idle , I'm not sure if that is a real fair test, but scanning seemed to stop afterwards.

02-13 13:51:25.479 5255-5255/com.example.myapplication D/CycledLeScanner: Set a wakeup alarm to go off in 9223372036854312311 ms: PendingIntent{d18298f: android.os.BinderProxy@5e9ef54}
02-13 13:51:25.479 5255-5255/com.example.myapplication D/CycledLeScanner: Stopping scanning previously left on.
02-13 13:51:25.479 1100-1327/? E/WifiAwareNativeApi: deleteAwareNetworkInterface: error: 9 (unknown)
02-13 13:51:25.479 5255-5255/com.example.myapplication D/CycledLeScanner: stopping bluetooth le scan
02-13 13:51:25.479 5255-5255/com.example.myapplication D/CycledLeScannerForLollipop: Stopping scan
02-13 13:51:25.479 1100-1135/? I/GnssLocationProvider: WakeLock released by handleMessage(SET_REQUEST, 0, com.android.server.location.GnssLocationProvider$GpsRequest@70173ac)
02-13 13:51:25.480 5255-5255/com.example.myapplication D/CycledLeScanner: Destroying
02-13 13:51:25.480 5255-5255/com.example.myapplication D/ScanJob: Scanning stopped
02-13 13:51:25.480 5255-5255/com.example.myapplication D/ScanJob: Checking to see if we need to start a passive scan
02-13 13:51:25.480 5255-5255/com.example.myapplication I/ScanJob: We are inside a beacon region.  We will not scan between cycles.
02-13 13:51:25.481 1100-1135/? I/GnssLocationProvider: WakeLock released by handleMessage(SET_REQUEST, 0, com.android.server.location.GnssLocationProvider$GpsRequest@6f9407b)
02-13 13:51:25.483 5255-8671/com.example.myapplication D/CycledLeScannerForLollipop: Stopping LE scan on scan handler
02-13 13:51:25.484 5255-8671/com.example.myapplication D/BluetoothAdapter: isLeEnabled(): ON
02-13 13:51:25.484 5255-8671/com.example.myapplication D/BluetoothLeScanner: could not find callback wrapper
02-13 13:51:25.484 5255-8671/com.example.myapplication D/CycledLeScanner: Quitting scan thread

Is that message about the wake up alarm a problem, that's a lot of ms?

02-13 13:51:25.479 5255-5255/com.example.myapplication D/CycledLeScanner: Set a wakeup alarm to go off in 9223372036854312311 ms: PendingIntent{d18298f: android.os.BinderProxy@5e9ef54}

What I am trying to get at, is it doesn't seem possible, to reliably scan for advertisements (even ignoring battery usage) without there being a window where >= Android 8 decides not to scan. Is this correct?

Thanks again

@davidgyoung
Copy link
Member

@jonface, a few points about the log excerpt shown above:

  1. The wakeup alarm is used for Android 4.3-7.x to keep the long-running scanning service going (restarting it with the alarm if needed.) When the alarm is "cancelled" is is actually given a time in the distant future to avoid being blocked on Samsung devices for creating too many alarms. This is the reason you see this, but it will have no affect on Android 8.

  2. The log excerpt shows that a ScanJob has completed, and scanning has been stopped because of this. A ScanJob will run for the configured backgroundScanPeriod or foregroundScanPeriod, whichever is active. The reason scanning stopped is because is period expired.

  3. The log shows that beacons have been recently detected, so a low power intent-backed scan between scan cycles is not started after the ScanJob ends. This only starts if you are in a location with no visible beacons so you can get a quick update if a beacon does appear.

After a ScanJob ends, a new one will be scheduled to start. If the app is in the foreground, the new one will start after the foregroundScanPeriod ends. If the app is in the background, the new one will start after the backgroundScanPeriod ends (or ~15 minutes per Android background job scheduling restrictions, whichever is longer). At this time you should start getting detections again. It is important to note that while this limit is nominally 15 minutes, Android can vary the schedule, and I have seen it take up to 25 minutes. I wrote a blog post about the detection times you can expect here

You are correct that Android 8 does not let you do more than scanning for ~10 minutes every ~15 minutes when your app is in the background and beacons are present. When beacons are not present, you can scan indefinitely for them until one appears.

Is my description above consistent with what you are seeing?

@jonface
Copy link
Author

jonface commented Feb 14, 2018

OK that's great, I can only assume I got impatient at some point and scanning would have resumed, but I had assumed it was broken. So from what you are saying, it is, unfortunately, working as designed.

Ideally I wanted to be able to move around and roughly know where I was, based on the visible beacons, but it seems this is not going to be reliable on Android 8 phones, unless Google change something.

Thanks again for taking the time to explain this, I did read your blog post on this topic, I was just hoping I had misunderstood it.

Cheers

@davidgyoung
Copy link
Member

Closing this because it sounds like this is working as designed. @jonface please reopen if you have test results that show it does not resume after ~15 minutes in this case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants