Android application: scan callbacks stop when screen is off

We have an Android application developed in Kotlin which uses the Nordic scanner library (Android-Scanner-Compat-Library) version 1.6.0.  It scans for devices which use the nRF52840. Our app specifies compileSdkVersion 31, minSdkVersion 26, targetSdkVersion 31.

In our app, we periodically stop BLE scanning and restart it. When the screen is off or the app is minimized, scanning/scan callbacks continue to work until one of the periodic intervals comes around to stop and restart scanning. When scanning is restarted, we no longer receive any scan callbacks from BLE advertisements.

Nordic documentation for the Android BLE Scanner Compat Library states "Note, that for unfiltered scans, scanning is stopped on screen off to save power. Scanning is resumed when screen is turned on again. To avoid this, use scanning with desired ScanFilter." This doesn't appear to be our problem for 2 reasons:

  • we are using a scan filter
  • with the screen off, the scan callbacks continue to work until we explicitly stop and restart scanning

We use SCAN_MODE_LOW_LATENCY for our scanning, which we understand will be more power hungry. Nordic documentation mentions the following about SCAN_MODE_LOW_POWER: "Perform Bluetooth LE scan in low power mode...This mode may be enforced if the scanning application is not in foreground."  Could our issue be that even though we are specifying SCAN_MODE_LOW_LATENCY, the system is automatically switching over to use SCAN_MODE_LOW_POWER when we restart scanning? If so, it seems surprising that we receive NO scan callbacks at all.

Thank you for your help with this issue.

John

  • No problem, I'm happy to help. Please feel free to close this question at your convenience.

  • I wanted to provide an update to this issue. In our case, getting scan results via PendingIntent did not work. As explained below, our problem was related to app permissions.

    To continue to get scan results when the app is in the background or screen is locked, the app needs to have permission ACCESS_BACKGROUND_LOCATION. On Android 10 or earlier, when first installing/launching the app and the user is prompted to accept location permission, they can specify option "Allow all the time". In addition to allowing the ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permission, my understanding is that this also implicitly gives the app the ACCESS_BACKGROUND_LOCATION permission.

    Starting with Android 11, this changed. When prompting for location permission on Android 11 or later, there is no "Allow all the time" option; at most there is a permission level to use location "While using the app". This DOES NOT provide the implicit ACCESS_BACKGROUND_LOCATION permission. The user can manually go to Settings on the phone and go to the App's location permissions and specify "Allow all the time". Better solution would be to prompt the user for this permission; I haven't tried it yet, but the following page discusses how to do this (looks like the app needs to prompt for ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permission first and then on the response to that then prompt for ACCESS_BACKGROUND_LOCATION permission):

    https://stackoverflow.com/questions/64246883/android-11-users-can-t-grant-background-location-permission

    Also see the following page for more information about this issue:

    https://developer.android.com/training/location/permissions#request-background-location

    Best regards,

    John

  • I'm sorry my suggestion didn't work, and thanks a lot for updating us about your findings, John. It is very helpful for the community.

    If you feel satisfied with your answer, please feel free to verify it any time.

    Best regards,

    Hieu

Related