AltBeacon / android-beacon-library

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

Scanning stops on Huawei P20 when screen is off #778

Open korneeld opened 5 years ago

korneeld commented 5 years ago

Expected behavior

I want to do continuous BLE scanning while the screen is off (using a Foreground Service). When the screen is on I see my advertisements showing up in the logs (eg. D/BeaconParser: Processing pdu ...).

Actual behavior

When the screen is turned off, the scanning stops after about 10 seconds.

Steps to reproduce this behavior

Run the reference application with a foreground service and without the battery saver nearby some BLE beacons. Check if beacons show up in the logs. Turn off the screen and wait for 10 seconds. As you can see in the logs below, there seems to be a program called 'Ash' that freezes the reference application.

Mobile device model and OS version

Huawei P20 lite - android 8.0.0

Android Beacon Library version

most recent (20/11/2018)

Relevant logs

... 11-20 17:51:46.584 13112-14158/org.altbeacon.beaconreference D/BeaconParser: Processing pdu ... ... 11-20 17:51:46.617 1825-2511/? I/ash: ignore front app :org.altbeacon.beaconreference screen off:12032ms org.altbeacon.beaconreference is front app ignore front app :org.altbeacon.beaconreference screen off:12033ms 11-20 17:51:46.619 1825-2511/? I/ash: org.altbeacon.beaconreference { doze duration=6026 UptimeDuration=6026 } transition to: hibernation reason: perform hibernation actions: org.altbeacon.beaconreference 11-20 17:51:46.621 1280-1831/? D/SmartHeartBeat: setAlarmsPending ... 11-20 17:51:46.621 1825-2511/? I/ash: Pending org.altbeacon.beaconreference alarm OK ! 11-20 17:51:46.622 1825-2511/? I/ash: stop ble scan:org.altbeacon.beaconreference 11-20 17:51:46.622 1825-2511/? D/BluetoothLeScanner: stopLeScanByPkg() org.altbeacon.beaconreference 11-20 17:51:46.624 10880-30713/? D/btservice-BluetoothAdapterService: getAdapterService() - returning com.android.bluetooth.btservice.AdapterService@ced311e 11-20 17:51:46.627 10880-30713/? W/Bth-btfreeze: BluetoothFreeze:tag: 182 uid: 10148 11-20 17:51:46.627 1825-2511/? I/BluetoothState: stop app ble scan: org.altbeacon.beaconreference OK. 11-20 17:51:46.629 1280-1831/? D/GpsFreezeProc: addFreezeProcess enter addFreezeProcess pkg:org.altbeacon.beaconreference 11-20 17:51:46.629 1825-1954/? I/PGServer: report state:8 event type:2 pid:0 uid:10148 pkg:null to pid: 1280 11-20 17:51:46.629 1825-1954/? I/BluetoothState: inactive bluetooth uid: 10148, pid:13112, reason:BLE_SCAN 11-20 17:51:46.630 1825-1954/? D/BluetoothState: stop bt uid:10148 state:BLE_SCAN total(ms):273500 11-20 17:51:46.630 1825-2511/? I/ash: proxy gps:org.altbeacon.beaconreference,uid:10148,result:true 11-20 17:51:46.631 1280-1860/? I/PGManagerService: proxyService, type:0, list: [org.altbeacon.beaconreference] 11-20 17:51:46.633 1825-2511/? I/ash: proxy service org.altbeacon.beaconreference OK ! 11-20 17:51:46.634 1280-1860/? I/PGManagerService: proxyBroadcast:[org.altbeacon.beaconreference] proxy:true 11-20 17:51:46.635 1825-2511/? I/ash: proxy org.altbeacon.beaconreference broadcast OK ! delayMs:0 perform delay action: org.altbeacon.beaconreference 11-20 17:51:46.635 629-629/? I/Pged-IPgedBinderService: *action is 1, pid num is 2 11-20 17:51:46.635 629-629/? I/Pged-Freezer: freezePids Freeze process: 13112 11-20 17:51:46.637 1825-2511/? D/PgedBinderAdapter: frz ok, pid: [13112] 11-20 17:51:46.637 1825-2511/? I/PGServer: report state:6 event type:1 pid:0 uid:10148 pkg:org.altbeacon.beaconreference to pid: 1280 11-20 17:51:46.638 1825-2511/? I/ash: Freeze org.altbeacon.beaconreference OK ! 11-20 17:51:46.639 1280-1860/? I/PGManagerService: proxyWakeLockByPidUid, pid: 13112, uid: 10148, proxy: true 11-20 17:51:46.639 1825-2511/? I/ash: Proxy wakelock uid = 10148 pid = 13112 11-20 17:51:46.644 1825-2511/? I/AppManager: close sockets for uid : 10148, succ: true spend(ms):4 11-20 17:51:46.644 1825-2511/? I/ash: close sockets >> org.altbeacon.beaconreference, uids : [10148]

davidgyoung commented 5 years ago

I see from the logs that it references the OS being in doze mode (probably indicating the phone is motionless for awhile) as well:

11-20 17:51:46.619 1825-2511/? I/ash: org.altbeacon.beaconreference { doze duration=6026 UptimeDuration=6026 } transition to: hibernation reason:
perform hibernation actions: org.altbeacon.beaconreference

A few questions:

What happens if the phone starts moving? Does the foreground service resume?

If the phone is moving (e.g. in your pocket) but with the screen off for an extended period of time, does this still happen?

What happens if the screen comes back on? Does the foreground service automatically resume?

It may not be possible to stop this behavior on Huawei, but at least we can understand it as much as possible. We might then be able to design some workarounds to make its impact as minimal as possible.

korneeld commented 5 years ago

Yes, the 'doze mode' suprises me, because as I said the screen was just turned off. It seems strange to go in doze mode after 12 seconds. I also tried shaking the phone while the screen was off, but the scan still stopped. I suspect this is specific to huawei (or maybe this specific phone?) as it does not seem to behave like the android doze mode. The moment I turn the screen back on the scanning resumes.

davidgyoung commented 5 years ago

Thanks for the updates, @korneeld.

I have a Huawei P9 Lite with Android 7 which does not do this, so I suspect this is a Huawei EMUI customization on top of Android 8.

This is pretty disappointing. I'm not sure what to even suggest as a workaround. Anybody else see this?

oebb commented 5 years ago

Hi. We're working on a foreground tracking app and are seing exactly this behaviour. It looks like it's a general issue on newer Huawei Devices with 8.1 (and probably 8.0) like the P20 and Mate series. It can be manually solved by setting the power options for the app in the UI. We're already making an exception from powersavings in our app but it doesn't work in this Huawei case. Currently investing it deeper.

oebb commented 5 years ago

Hi again. Yes - this is really sad. There doesn't seem to be any really good workaround. It doesn't seem like it's possible to access the Huawei power options either. The closest we have got is to open the power option settings for affected users - using something like this https://gist.github.com/moopat/e9735fa8b5cff69d003353a4feadcdbc.

korneeld commented 5 years ago

Thanks for the update. I found that for Huawei P20 I needed this component: com.huawei.systemmanager.appcontrol.activity.StartupAppControlActivity

There you can change the battery settings to 'manage manually'.

davidgyoung commented 5 years ago

@korneeld can you share a code snippet of what you did, and describe a bit more what affect this has?

korneeld commented 5 years ago

No real solution to the problem I'm afraid ... I was referring to the answer of @oebb about opening the power settings. The standard Android-way of disabling battery optimisations is not enough. If you follow the github-link there are a bunch of manufacturer-specific Activity's for disabling powing-optimisations (see getComponentNames()). To get it working on the P20 I had to change the Huawei Acitivity name to StartupAppControlActivity.

wojtik8 commented 5 years ago

You can use the MediaPlayer to periodically play a muted sound. This will prevent the Huawei ash service from hibernating your foreground service and turning off the BLE scan. However, it drains battery twice as fast. _mediaPlayer = MediaPlayer.create(this, Settings.System.DEFAULT_NOTIFICATION_URI ); _mediaPlayer.setLooping(false); _mediaPlayer.setVolume(0,0);