I'm working on an app that runs a background service to range bluetooth beacons in intervals.
I start a ForegroundService with a timer to start ranging beacons for 10 seconds every minute, with an interval of 200 millis, calculates the strongest beacon and submits it to the backend API.
This works neatly while the app is in foreground, and, when the screen is off, as long as i'm hooked up using adb logcat. As soon as I take it off, nothing gets submitted to the servers anymore, meaning that no beacons are being ranged anymore.
Here are the relevant code pieces, I hope I didn't simplify too much:
class BeaconService : Service(), BeaconConsumer {
private var beaconManager: BeaconManager? = null
private var rangingTimer = Timer("rangingTimer", true)
private val region = Region("com.beacon.test", Identifier.parse("f7826da6-4fa2-4e98-8024-bc5b71e0893e"), null, null)
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return Service.START_STICKY
}
override fun onCreate() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationManager = MyNotificationManager.getInstance()
val notification = notificationManager.buildBeaconServiceNotification(this, "iBeacon service", null)
startForeground(NOTIFICATION_ID, notification)
}
initBeaconManager()
}
private fun initBeaconManager() {
BeaconManager.setDebug(true)
beaconManager = BeaconManager.getInstanceForApplication(this)
beaconManager?.foregroundScanPeriod = 200L
beaconManager?.beaconParsers?.add(BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"))
beaconManager?.bind(this)
}
override fun onBeaconServiceConnect() {
beaconManager?.addRangeNotifier { beacons, _ ->
if (beacons.isNotEmpty()) {
//code add ranged beacons to list
}
}
startRanging()
}
private fun startRanging() {
//code to reset the list of ranged beacons
beaconManager?.startRangingBeaconsInRegion(region)
rangingTimer.schedule(10000L) {
stopRanging(50000L)
}
}
private fun stopRanging(restartRangingAfter: Long? = null) {
beaconManager?.stopRangingBeaconsInRegion(region)
//code calcuate the strongest beacon and submit to server
if (restartRangingAfter != null) {
rangingTimer.schedule(restartRangingAfter) {
startRanging()
}
}
}
}