question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Doze mode locks scan?

See original GitHub issue

Expected behavior

Scanner works when device is locked or how we can to check is scanner locked by OS?

Actual behavior

Periodically scanner stops

Steps to reproduce this behavior

Run scanner with foreground service and lock device. Sometimes didRangeBeaconsInRegion not called.

Mobile device model and OS version

Samsung Galaxy S6 edge+ (Android 7.0)

Android Beacon Library version

2.15.2

I’m not sure that this question should be a issue. Briefly:

When method addRangeNotifier invoked, i iterate by beacon collections (in method didRangeBeaconsInRegion argument) and add it into List<> if not exsits, or update last visible time parameter (modifiedAt = System.currentTimeMillis()) if beacon was already in list.

Every 10 seconds my background thread iterates through this collection (List<>) and checks modifiedAt field. If we saw beacon more than 1 minute ago i remove it from collection. So i guess that we left the zone.

But. If device in idle state, periodically we do not receive events.

It’s mean (Situation1) :

  1. User enters in zone (new beacon, not exists in our cache, in our List<>)
  2. User locks screen and does not leave the zone.
  3. For a while we get an events, all is good, great.
  4. After a while didRangeBeaconsInRegion stop calling.
  5. Sooner or later didRangeBeaconsInRegion invokes again

I guess it’s doze mode, but im not sure because see something strange (method for adding beacon or update it modifiedAt field):

fun addBeacon(beacon: AppBeacon) {
        if (isInDozeMode(TheApplication.getInstance())) {
            Crashlytics.logException(InconsistencyStateException("addBeacon invoke but doze mode active"))
       }
      //next logic
fun isInDozeMode(context: Context) : Boolean {
    val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && powerManager.isDeviceIdleMode
}

And in reports i see this exception. I mean we obtain callback from library but isInDozeMode returns true.

For avoiding [Situation1] i added condition inside looper thread (thread that clean up expired objects).

if (isInDozeMode()) {
   //Ignore check modifiedAt parameter.
} else {
  //Check modifiedAt. If >1minute remove it
}

Unfortunately this condition does not work perfectly.

So, my question. Can we check is scanner not available now (blocked by OS)? Thanks.

Attachment: scanner setup in Application instance class

private const val REGION_UID = "my.packagename.here"
        private val region : Region
        get() {
            return Region(REGION_UID, null, null, null)
        }
const val FOREGROUND_BETWEEN_SCAN_DELAY: Long = 1000L
const val BACKGROUND_BETWEEN_SCAN_DELAY: Long = 1000L

const val FOREGROUND_SCAN_PERIOD: Long = 2000
const val BACKGROUND_SCAN_PERIOD: Long = 5100


 private fun setupBeaconScanner() {
        LogManager.setLogger(BeaconLogger())

        beaconManager = BeaconManager.getInstanceForApplication(this)
        beaconManager!!.beaconParsers.clear()
        beaconManager!!.beaconParsers.add(AltBeaconParser())
        beaconManager!!.beaconParsers.add(BeaconParser().setBeaconLayout(BeaconParser.URI_BEACON_LAYOUT))
        beaconManager!!.beaconParsers.add(BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_TLM_LAYOUT))
        beaconManager!!.beaconParsers.add(BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT))
        beaconManager!!.beaconParsers.add(BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_URL_LAYOUT))
        beaconManager!!.beaconParsers.add(BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"))

        val notificationBuilder = NotificationCompat.Builder(this)
        notificationBuilder.setSmallIcon(R.drawable.ic_details_action)
        notificationBuilder.setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.ic_details_action))
        notificationBuilder.setContentTitle("Scanning for beacons")
        val intent = Intent(this, MainActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(this, MainActivity.BEACON_REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT)
        notificationBuilder.setContentIntent(pendingIntent)


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channelId = createNotificationChannel(SCANNER_CHANEL_ID, SCANNER_CHANEL_NAME, SCANNER_IMPORTANCE)
            notificationBuilder.setChannelId(channelId)
            notificationBuilder.setBadgeIconType(BADGE_ICON_SMALL)
        }

        val notification = notificationBuilder.build()
        beaconManager!!.enableForegroundServiceScanning(notification, 456)

        beaconManager!!.addRangeNotifier { p0, p1 ->
            p0?.run {
                forEach {
                    val beacon = AppBeacon.fromLibraryBeacon(it)
                    if (beacon != null) {
                        AppBeaconManager.addBeacon(beacon 
                    }
                }
            }
        }
        beaconManager!!.addMonitorNotifier(this)
        beaconManager!!.setEnableScheduledScanJobs(false)
        beaconManager!!.backgroundBetweenScanPeriod = BACKGROUND_BETWEEN_SCAN_DELAY
        beaconManager!!.foregroundBetweenScanPeriod = FOREGROUND_BETWEEN_SCAN_DELAY
        beaconManager!!.backgroundScanPeriod = BACKGROUND_SCAN_PERIOD
        beaconManager!!.foregroundScanPeriod = FOREGROUND_SCAN_PERIOD

        regionBootstrap = RegionBootstrap(this, region)
// Power saver temporary excluded but it did not fix the situation.
//        backgroundPowerSaver = BackgroundPowerSaver(this)

    }

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:22 (10 by maintainers)

github_iconTop GitHub Comments

2reactions
davidgyoungcommented, Jan 31, 2019

Yes, so long as ranging is active, didRangeBeconsInRegion is called with a zero length collection of beacons when none are in range.

1reaction
davidgyoungcommented, Jan 31, 2019

If you are ranging, then a call to didRangeBeaconsInRegion indicates the time the last scan cycle completed. If you see these stop, then the scan cycles have stopped for some reason.

I suspect you can test on your OnePlus despite custom behavior that kills the app in the background. You can either whitelist your app to in the OnePlus settings so it can run forever, or you can simply use an ADB command to force entering doze mode immediately: $ adb shell dumpsys deviceidle force-idle

Read more comments on GitHub >

github_iconTop Results From Across the Web

Optimize for Doze and App Standby | Android Developers
In Doze or App Standby mode, the system delivers the message and gives the app temporary access to network services and partial wakelocks,...
Read more >
Android Battery Optimization for Avoiding Doze Mode and App ...
The system ignores wake locks;; A network connection is not available;; The system doesn't perform WiFi, WiFi RTT, and BLE scans; ...
Read more >
Scanning for Bluetooth LE devices when the phone is in doze ...
Scanning is a very expensive operation that Android won't allow in the background. Instead, make an attempt to connect to the device.
Read more >
How does Doze mode save battery power? - HTC SUPPORT
Wi‍-Fi® scans will not be performed even if your Wi‍-Fi® connection is on. Apps will not have network access. Background activities such as...
Read more >
Diving into Doze Mode for Developers - Big Nerd Ranch
The operating system will also ignore any wakelocks attempted by the application, which means work must be completed within the maintenance ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found