AltBeacon / android-beacon-library

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

Android Pie (Nokia) - Foreground Scanning Service scans for sometime and then scanning stops when app is in background. #807

Open shriharsha-bhagwat opened 5 years ago

shriharsha-bhagwat commented 5 years ago

Expected behavior

When Foreground scanning service is enabled it should scan always

Actual behavior

Scanning works for sometime(1-2 hours) and then scanning stops when the app is kept in background for a long time.

Steps to reproduce this behavior

Let the scan start and leave mobile idle for more than 2 hours. Scanning return empty list of beacons I have attached code.

Mobile device model and OS version

Nokia 6.1 Android PIe OS Version 9

Android Beacon Library version

2.15

My Code: How can i run the scanning for a long time (10-12 hours) continuously on Android 8 and Android 9?

beaconManager = BeaconManager.getInstanceForApplication(context);
        beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
        beaconManager.setForegroundScanPeriod(1500);
        beaconManager.setBackgroundScanPeriod(1500);
        if (!beaconManager.isBound(this)) {
            String NOTIFICATION_CHANNEL_ID = BuildConfig.APPLICATION_ID;
            String channelName = "App Service";
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_DEFAULT);
                chan.setLightColor(Color.BLUE);
                chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
                NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
                assert manager != null;
                manager.createNotificationChannel(chan);
            }
            Intent intent = new Intent(context, LandingScreen.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(
                    context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT
            );
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
                    .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
                    .setSmallIcon(R.drawable.ic_logo_notification)
                    .setContentTitle("Scanning")
                    .setContentText("You are clocked IN")
                    .setStyle(new NotificationCompat.BigTextStyle().bigText("You are clocked IN"))
                    .setContentIntent(pendingIntent)
                    .setAutoCancel(true)
                    .setChannelId(NOTIFICATION_CHANNEL_ID);
            beaconManager.enableForegroundServiceScanning(notificationBuilder.build(), 5455);
            beaconManager.bind(this);
cobainmo commented 5 years ago

I can also confirm that above procedure with clearing cache is not working on Nokia 8 Android 9 (with latest security patch installed) along with soft reset. I didn't have issue like @joew46167 it started normally, but i still keep getting "Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results".

@davidgyoung since i am trying to switch app from using "Estimote" library to AltBeacon i can confirm you that this issue does not occur on Estimote and Beacon scanner is working properly. I dont know if it helps you but id does not seem its just Nokia side issue.

joew46167 commented 5 years ago

@cobainmo that's interesting that the Estimote API doesn't give you this issue.

I previously had rolled my own BLE scanner, and I see this issue with my handler as well. That was part of the motivation for switching - I had hoped to have better results with the library.

For most phones, it is better. For the Nokia, it's about the same

cobainmo commented 5 years ago

@joew46167 yes, i can confirm that. I have access to 30 different devices with android 9 Including various Nokias that have Estimote lib and its working.

To be honest i had same behaviour with few different brand. It has same issue as Nokia but different logs. Point is it stops after a while then come back by itself.

I will take few day to test it in detail and probably open new issue if it turns out not to be Nokia problem.

cobainmo commented 5 years ago

Hello, is there any new info about this issue?

Last 5 days i was running test on few Nokia devices as well as other manufacturers with android 9. Problem is definitely related to Nokia. On other vendors works fine. On the other side, Estimote lib still works on Nokia 8, Nokia 7.1 with android 9 so it got to be related to Altbeacon lib.

Log:

02-04 12:01:33.870 28045-28045/nsoft.navi.claim.claimerwmp E/CycledLeScannerForLollipop: Scan failed: a BLE scan with the same settings is already started by the app 02-04 12:01:33.969 31631-31647/? V/FA: Inactivity, disconnecting from the service 02-04 12:01:38.932 990-1122/? E/storaged: getDiskStats failed with result NOT_SUPPORTED and size 0 02-04 12:01:42.949 28045-28491/nsoft.navi.claim.claimerwmp D/BluetoothAdapter: isLeEnabled(): ON 02-04 12:01:42.959 28045-28491/nsoft.navi.claim.claimerwmp D/BluetoothAdapter: isLeEnabled(): ON 02-04 12:01:42.967 6288-6327/? I/bt_stack: [INFO:gatt_api.cc(949)] GATT_Register4b7a2d5f-3f1f-22de-3261-c1ea920ff9f7 [INFO:gatt_api.cc(969)] allocated gatt_if=5 02-04 12:01:42.968 28045-31707/nsoft.navi.claim.claimerwmp D/BluetoothLeScanner: onScannerRegistered() - status=0 scannerId=5 mScannerId=0 02-04 12:01:42.978 28045-31707/nsoft.navi.claim.claimerwmp W/Binder: Binder call failed. java.lang.SecurityException: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results at android.os.Parcel.createException(Parcel.java:1950) at android.os.Parcel.readException(Parcel.java:1918) at android.os.Parcel.readException(Parcel.java:1868) at android.bluetooth.IBluetoothGatt$Stub$Proxy.startScan(IBluetoothGatt.java:947) at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper.onScannerRegistered(BluetoothLeScanner.java:460) at android.bluetooth.le.IScannerCallback$Stub.onTransact(IScannerCallback.java:57) at android.os.Binder.execTransact(Binder.java:731) 02-04 12:01:43.536 1448-1607/? I/ActivityManager: Start proc 31710:n.home.smartapp/u0a262 for broadcast n.home.smartapp/.widget.WidgetProvider 02-04 12:01:43.536 1448-1607/? D/ActivityManager: handleProcessStartedLocked mDoneFinishBooting && app.pid != 0 ---> notifyProcessStart, app.processName = n.home.smartapp, app.info = ApplicationInfo{4fe5261 n.home.smartapp}, app.hostingType = broadcast, getHostingName() = ComponentInfo{com.google.android.dialer/com.android.voicemail.impl.StatusCheckJobService}, getIntentFlag() = 0, getIsPackageRunning() = false, app = ProcessRecord{568d186 31710:n.home.smartapp/u0a262}, getExtraData() = Bundle[{SERVICE_INTENT=Intent { cmp=com.google.android.dialer/com.android.voicemail.impl.StatusCheckJobService }, CALLER_PACKAGE=android}] 02-04 12:01:43.537 1448-2414/? V/ActivityManager: notifyProcessStart: n.home.smartapp for: broadcast from: android packageName: com.google.android.dialer className: com.android.voicemail.impl.StatusCheckJobService 02-04 12:01:43.547 31710-31710/? E/n.home.smartap: Not starting debugger since process cannot load the jdwp agent. 02-04 12:01:43.549 22363-22363/? I/BgTaskExecutorImpl: Starting PERIODIC background task REFRESH_SEARCH_HISTORY. 02-04 12:01:43.557 1448-1607/? I/ActivityManager: Start proc 31723:com.google.android.dialer/u0a86 for service com.google.android.dialer/com.android.voicemail.impl.StatusCheckJobService 02-04 12:01:43.557 1448-1607/? D/ActivityManager: handleProcessStartedLocked mDoneFinishBooting && app.pid != 0 ---> notifyProcessStart, app.processName = com.google.android.dialer, app.info = ApplicationInfo{26cb39d com.google.android.dialer}, app.hostingType = service, getHostingName() = ComponentInfo{com.google.android.dialer/com.android.voicemail.impl.StatusCheckJobService}, getIntentFlag() = 0, getIsPackageRunning() = false, app = ProcessRecord{f708012 31723:com.google.android.dialer/u0a86}, getExtraData() = Bundle[{SERVICE_INTENT=Intent { cmp=com.google.android.dialer/com.android.voicemail.impl.StatusCheckJobService }, CALLER_PACKAGE=android}] 02-04 12:01:43.558 1448-2414/? V/ActivityManager: notifyProcessStart: com.google.android.dialer for: service from: android packageName: com.google.android.dialer className: com.android.voicemail.impl.StatusCheckJobService 02-04 12:01:43.569 3102-3102/? E/CarrierServices: [2] ben.F: Cannot access P-CSCF address, RCS configuration is null! 02-04 12:01:43.570 3102-3102/? E/CarrierServices: [2] ben.A: Cannot access P-CSCF port, IMS configuration is null!

joew46167 commented 5 years ago

@cobainmo To be honest, I've moved on, and have just put in a check to see it is still connected to the beacon scanner, and if not I tell the user (my app speaks anyway, as it is for blind people) that if they turn the screen on for a moment it will likely solve the issue.

It is interesting that the Estimate API has found a way around this. I wonder if it might have to do with frequency of restarting the scan? I believe that the library is currently restarting every 29 minutes - just often enough to circumvent the 30 minute issue. After my testing, my gut feeling (with no true evidence or testing) is twofold:

  1. That even if the timer had been only 10 minutes this issue would still be present
  2. A more frequent scan update - say every 1 minute - might work

I also have a feeling that Google will catch on to our attempts to circumvent the 30 minute limit and shut that down, too.

davidgyoung commented 5 years ago

@joew46167 why do you think restarting a scan every 1 min would help?

I am certainly open to ideas like this to try, as I don't know what is different about the estimote approach that would make it work. (They might not know either, it is probably by accident!)

joew46167 commented 5 years ago

@davidgyoung I'm about to do a test, but if I remember correctly, my hand built BLE code didn't have this issue with Nokia phones. And I was doing restarts every minute.

It's been a while since I've used that code, I've slept since then, and I just can't be sure if I had the issue or not. As I said, though, I am going back to that code now and testing - I have other tests to do in that code as well. I'll let you know the results.

cobainmo commented 5 years ago

@davidgyoung i think you are right about Estimote and accident since they have other more obvious issues unsolved.

Anyway this lib works great and i will leave estimote just for Nokia phones for now. If in some future you find out solution let me know.

@joew46167 i'm moving on too :) at some point i just doubted that it is only Nokia issue. After all testing, looks like i was wrong.

joew46167 commented 5 years ago

@cobainmo I worry that your fear could be correct, that it's not just for Nokia, so I left my code agnostic - I do the check and make the suggestion to unlock the device for all devices, not just Nokia.

joew46167 commented 5 years ago

@davidgyoung My memory was wrong. My hand rolled BLE handler does indeed fail and presents the permissions error. In it I restart the scanner every minute. At the 10 minute mark is when the permissions error occurs.

I wonder if the Estimote library found a way to not require the periodic restart, and that is how they bypass the issue?

jochemc commented 5 years ago

I had the same issue (with my own code). In addition, I had my app being killed after some time (I am using the Foreground service approach). After some searching, the latter apparently was due to aggressive service killing on the Nokia, as reported here: https://dontkillmyapp.com/nokia. Killing the killer as instructed on that site fixed this, but also appears to silence the issue being reported/discussed in this thread (ie I saw no more scan security exceptions). I have no time to further investigate or reproduce this, but it may be a useful piece of information, hence this post.

shriharsha-bhagwat commented 5 years ago

For me the Settings provided by Nokia (clearing storage etc) did not work on my Nokia 6.1 running Android 9. What worked is force stopping the PowerSaver.G3 system app inside Nokia. Scan runs smoothly for hours if i force stop the PowerSave.G3.

paulpv commented 4 years ago

I just noticed the following in the reference app's manifest, maybe it would resolve this issue?

        <!-- uncomment the following to enable scanning for over 30 minutes on Android 7+ -->
        <service android:name="org.altbeacon.beacon.service.BeaconService"
            tools:node="replace">
            <meta-data android:name="longScanForcingEnabled" android:value="true"/>
        </service>
tc14077 commented 4 years ago

Any updates on this issue? HMD Global (i.e. Nokia) claims to disable Evenwell powersaving apps on all devices running Android Pie or newer which means the foreground scanning service may be able to run in background. See here: https://community.phones.nokia.com/discussion/51246/tapping-into-android-pies-adaptive-battery-for-optimum-battery-performance

I tested my app on a Nokia phone(Nokia 7.2 with the latest android version). My app is able to run in the background for more than an hours. However, the beacon scanning(with using Foreground Service Scanning approach) is found to be stopped after 30 minutes background operation.