AltBeacon / android-beacon-library

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

Forced Low Power Scanning in Background Causes Missed Detections on Samsung #483

Open fabriziogueli opened 7 years ago

fabriziogueli commented 7 years ago

Expected behavior

App go to background and still able to scan & detect beacon every second.

Actual behavior

After app go to background, it detect few times the beacon and i can see in the log:

BtGatt.GattService: Its third party background application, change scanmode to low power

Steps to reproduce this behavior

When the app goes in background i start my foreground service that binds the BeaconService (i need to show to the user an ongoing notification and i want to avoid that Android kills my service).

FYI: I'm developing a real time tracking application, so i need to show to the user a notification that indicate the tracking is current enabled and i use a Foreground service because is not a candidate for the system to kill when low on memory.

I set the BackgroundScanPeriod to 1100 and the BackgroundBetweenScanPeriod to 0.

Mobile device model and OS version

Mobile Devices: Samsung Galaxy S7 with Android 7.0

Using a Huawei Nexus 6P with Android 7.1.1 and with a Motorola Moto E with Android 6.0 the system works as expected. In background i detect the beacons every second.

Android Beacon Library version

android_beacon_library2.9.2

davidgyoung commented 7 years ago

Is this exactly what you see in the log: "BtGatt.GattService: Its third party background application, change scanmode to low power"?

Are there any other lines you see in context that are useful?

Do you ever see any detections after you see this line?

Does your app use BackgroundPowerSaver?

It would be useful if you could set beaconManager.setDebug(true); then capture a log between the time your foreground service starts up and the time it stops detecting.

fabriziogueli commented 7 years ago

Hi David, yes i see exactly that line. After that line i detect beacons less frequently, even if the DidRange callback is called regularly. But the callback returns less beacons than when in foreground or even no beacons at all.

I'm not using the BackgroundPowerSaver neither the RegionBootStrap.

I have attached two files. BtGatt Logs when the app is in foreground and i start scan in my Application and logs when the app is in background and i bind the service in my foreground service.

BackgroundLog.txt LogForeground.txt

I have attached also a small log of the beacon library when the app is in background. BeaconLibraryLog.txt

Thanks for your support.

davidgyoung commented 7 years ago

I see from the background log, it is attempted to start a high power, low-latency scan:

D/CycledLeScannerForLollipop: starting non-filtered scan in SCAN_MODE_LOW_LATENCY

But it appears that the Samsung device you tested overrides this setting per the debug line below:

D BtGatt.GattService: Its third party background application, change scanmode to low power

The second line above does not appear in the AOSP code, so I suspect this is a vendor-specific addition to Android that forces any apps that are not in the foreground to only scan for bluetooth in low power mode, even if a non-low power mode was requested. This hypothesis is supported by the fact that you do not see this on non-Samsung phones.

The default recommended use of the Android Beacon Library is to do low power scanning in the background, but it is understandable that you may wish to override this for specific use cases with high power background scans, especially if you let the user know you are doing this by having a foreground service indicator.

Unfortunately, there may be no way around this on (at least some) Samsung devices, if they enforce this policy on apps in the background.

Two things you may try:

  1. Disable Android L Scanning with the library to see if this makes a difference: BeaconManager.getInstanceForApplication(this).setAndroidLScanningDisabled(true);

  2. Make the internal BeaconService created by the library (this is what actually does the scanning) a foreground service to see if this makes a difference. The library does not support this out of the box. If you are up for modifying the library itself, you could try modifying the way the service is started in BeaconManager.java to call with startForeground.

fabriziogueli commented 7 years ago

Thanks for the answer David. I also thought that it was a vendor specific behavior. At the beginning i thought that the problem was caused by the Samsung Energy Saving Mode, but i removed my application from those monitored by the OS and the problem still occurs.

I just tried your suggestions in the previous days but with no luck.

The system works a little better with BackgroundScanPeriod set to 5000, but sometimes the library doesn't see a specific beacon for more than 60 seconds.

I will do other tests and i will let you know

Thanks

davidgyoung commented 7 years ago

Another report of this here:

http://stackoverflow.com/questions/43173961/android-altbeacon-library-stop-find-beacons-every-1-second-when-app-in-backgroun

fjserrano commented 7 years ago

Hi. I am testing in a samsung galaxy J and other samsung model (I don't remember which) with android 5.0 and I don't know if it is the same issue, but i detect my service and background scanning stops randomly. I disabled all features for save battery in the system, but always it puts the service and the background scanning in pause.

This behaviour happens when is not charging and is not connected via microusb to PC. I detect this making a service with a timer of 2 seconds and making device vibrate for 200 ms. When shutdown the screen the phone is vibrating every 2 seconds but passed around 1 minute, the device stops of vibrating. After a while the service starts again to vibrating during 10 seconds and go to sleep again, this behaviour happened to me on every APP that I Tested. I think this is by the fork of Android for samsung devices, It puts all services in pause to save battery and wakes up to keep going the services and put again in pause.

It's a torture but I did a workaround to detect if service comes from pause state to make my decision for beacons, but the torture is beacuse I don't have control about the time for pause or wake the phone and you don't have the control of the time for the App.

davidgyoung commented 7 years ago

@fjserrano, what do you mean by "but always it puts the service and the background scanning in pause"? Do you see something in the logs?

fjserrano commented 7 years ago

Yes, I see in logs how it can enter in state that is not working, I don´t know if is pause, or other but is not running. If I have time I put a log to see this. One of the samsung can be upgrade to 6.0. I want to upgrade to know if with 6.0 have the same behaviour.

fjserrano commented 7 years ago

@davidgyoung I put here 2 logs. 1 From my APP when the service every 2 seconds write, and the phone put the service locked or paused from "06-13 20:32:19.162" to "06-13 20:32:59.622".

In the log of system this is the message of log "06-13 20:32:18.602 D/ActivityManager( 1006): retrieveServiceLocked(): component = testexample.com.beaconble/org.altbeacon.beacon.BeaconIntentProcessor; callingUser = 0; userId(target) = 0" and the next log is "06-13 20:32:58.872 V/AlarmManager( 1006): waitForAlarm result :4" and in the next line the system bind my service.

If you need more data I can test. In the next days I'm going to upgrade to 6.0 and I see if the system have the same result.

samsungLogAPP.txt samsungLogSystem.txt

davidgyoung commented 7 years ago

@fjserrano, it's hard to figure out what is going on from those logs, especially since I don't know the details of how your app is written. That said, I do not see any log lines like mentioned above: D BtGatt.GattService: Its third party background application, change scanmode to low power so you are probably experiencing a different issue.

Please try to reproduce the issue with the reference app here: https://github.com/altbeacon/android-beacon-library-reference so we know we are working with a very simple codebase. Since your problem is about ranging beacons in the background, you may need to modify the reference app to have custom scan periods like below:

        beaconManager.setDebug(true);
        beaconManager.setBackgroundBetweenScanPeriod(100l);
        beaconManager.setBackgroundScanPeriod(1100l);

If you can reproduce the problem, and get some system logs, please open a new issue rather than appending to this one, since your case does appear to be different.