I have the following uses-case. I have an Android application which may be in different states:
- Foreground (user is using the app);
- Background (user is not using the app but it's app's task exists and user can open the app form TaskManager any-time);
- Killed (app is killed and not available in TaskManager)
I need to detect a BLE beacon for all of these states and for now just show a notification. I started with this AltBeacon library and it covers Foreground and Background BLE beacon detection scenarios. Library set up is straight-forward.
BeaconManager setup:
private lateinit var beaconManager: BeaconManager
beaconManager = BeaconManager.getInstanceForApplication(this)
Prepare Beacon configuration:
private fun prepareBeaconConfigurations() {
BeaconManager.getInstanceForApplication(this).setIntentScanningStrategyEnabled(true)
beaconManager.beaconParsers.clear()
val iBeaconLayout = "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"
val altBeaconLayout = "m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"
val iBeaconParser = BeaconParser().setBeaconLayout(iBeaconLayout)
val altBeaconParser = BeaconParser().setBeaconLayout(altBeaconLayout)
iBeaconParser.setHardwareAssistManufacturerCodes(arrayOf(0x004c).toIntArray())
beaconManager.beaconParsers.add(iBeaconParser)
beaconManager.beaconParsers.add(altBeaconParser)
}
Create Ranging and Monitoring observers:
private val centralRangingObserver = Observer<Collection<Beacon>> { beacons ->
val rangeAgeMillis =
System.currentTimeMillis() - (beacons.firstOrNull()?.lastCycleDetectionTimestamp ?: 0)
if (rangeAgeMillis < 10000) {
logger.logD(TAG, "Ranged: ${beacons.count()} beacons")
for (beacon: Beacon in beacons) {
logger.logD(TAG, "$beacon about ${beacon.distance} meters away")
}
} else {
logger.logD(TAG, "Ignoring stale ranged beacons from $rangeAgeMillis millis ago")
}
}
private val centralMonitoringObserver = Observer<Int> { state ->
if (state == MonitorNotifier.OUTSIDE) {
logger.logD(TAG, "Outside beacon region: $region")
sendNotification("A beacon connection is left.")
Toast.makeText(this, "A beacon connection is left.", Toast.LENGTH_SHORT).show()
} else {
logger.logD(TAG, "Inside beacon region: $region")
sendNotification("A beacon is nearby.")
Toast.makeText(this, "A beacon is nearby.", Toast.LENGTH_SHORT).show()
}
}
And final step start monitoring (when all required conditions like permissions, bluetooth ON e.t.c are met)
private fun initBeaconObserver() {
beaconManager.startMonitoring(region)
beaconManager.startRangingBeacons(region)
val regionViewModel =
BeaconManager.getInstanceForApplication(this).getRegionViewModel(region)
regionViewModel.regionState.observeForever(centralMonitoringObserver)
regionViewModel.rangedBeacons.observeForever(centralRangingObserver)
}
Having this config set up:
BeaconManager.getInstanceForApplication(this).setIntentScanningStrategyEnabled(true)
Solved the problem to detect BLE beacons when app is killed but it's not reliable. It was working a few times when I initially added this config but now it stopped working and I wonder why.
I'm looking for any advices that may help me with my use-case. Maybe exist other approaches to detect BLE beacons. The one I chose requires "All the tome location permission" and I can not be sure that user granted this important permission.
Additional details for troubleshooting: Android OS - Android 14 Device - Pixel 7
The steps for failed scenario
- Launch the app with the lib's configuration I left above.
- See the message that beacon is detected.
- Turn beacon off and on and see message is updated accordingly to beacon's status
- Kill the app and try the same steps (turn on and off the beacon) OR just go outside of beacon's range and nothing happens.
ADB logs:
2023-10-11 17:12:48.344 17290-17290 ScanJob com.testble.mobile I Using immediateScanJobId from manifest: 208352939
2023-10-11 17:12:48.390 17290-17290 ScanJob com.testble.mobile I Using periodicScanJobId from manifest: 208352940
2023-10-11 17:12:48.391 17290-17290 JobInfo com.testble.mobile W Requested interval +5m10s0ms for job 208352940 is too small; raising to +15m0s0ms
2023-10-11 17:12:48.391 17290-17290 JobInfo com.testble.mobile W Requested flex 0 for job 208352940 is too small; raising to +5m0s0ms
2023-10-11 17:12:48.460 17290-17290 ScanJob com.testble.mobile I ScanJob Lifecycle START: org.altbeacon.beacon.service.ScanJob@38e0c55
2023-10-11 17:12:48.610 17290-17364 ScanHelper com.testble.mobile D BeaconParsers set to count: 2
2023-10-11 17:12:48.610 17290-17364 ScanHelper com.testble.mobile D First parser layout: m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24
2023-10-11 17:12:48.610 17290-17364 CycledLeScanner com.testble.mobile I Using Android O scanner
2023-10-11 17:12:48.618 17290-17364 ScanJob com.testble.mobile I Using immediateScanJobId from manifest: 208352939
2023-10-11 17:12:48.619 17290-17364 ScanJob com.testble.mobile I Running immediate scan job: instance is org.altbeacon.beacon.service.ScanJob@38e0c55
2023-10-11 17:12:48.625 17290-17364 ScanJob com.testble.mobile I scanJob version 2.20-beta1 is starting up on the main process
2023-10-11 17:12:48.632 17290-17367 ScanHelper com.testble.mobile I Non-distinct packets detected in a single scan. Restarting scans unecessary.
2023-10-11 17:12:48.667 17290-17364 ModelSpeci...Calculator com.testble.mobile W Cannot find match for this device. Using default
2023-10-11 17:12:48.669 17290-17364 ModelSpeci...Calculator com.testble.mobile W Cannot find match for this device. Using default
2023-10-11 17:12:48.675 17290-17364 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:12:48.705 17290-17365 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:12:48.707 17290-17364 ScanJob com.testble.mobile I Scan job running for 10000 millis
2023-10-11 17:12:48.712 17290-17305 BluetoothLeScanner com.testble.mobile D onScannerRegistered() - status=0 scannerId=3 mScannerId=0
2023-10-11 17:12:58.711 17290-17290 ScanJob com.testble.mobile I Scan job runtime expired: org.altbeacon.beacon.service.ScanJob@38e0c55
2023-10-11 17:12:58.727 17290-17290 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:12:58.747 17290-17365 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:12:58.890 17290-17290 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:12:59.157 17290-17290 ScanJob com.testble.mobile I Using immediateScanJobId from manifest: 208352939
2023-10-11 17:12:59.190 17290-17290 ScanJob com.testble.mobile I Using periodicScanJobId from manifest: 208352940
2023-10-11 17:12:59.190 17290-17290 JobInfo com.testble.mobile W Requested interval +5m10s0ms for job 208352940 is too small; raising to +15m0s0ms
2023-10-11 17:12:59.191 17290-17290 JobInfo com.testble.mobile W Requested flex 0 for job 208352940 is too small; raising to +5m0s0ms
2023-10-11 17:12:59.231 17290-17290 ScanJob com.testble.mobile I ScanJob Lifecycle START: org.altbeacon.beacon.service.ScanJob@2147653
2023-10-11 17:12:59.461 17290-17376 ScanHelper com.testble.mobile D BeaconParsers set to count: 2
2023-10-11 17:12:59.461 17290-17376 ScanHelper com.testble.mobile D First parser layout: m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24
2023-10-11 17:12:59.461 17290-17376 CycledLeScanner com.testble.mobile I Using Android O scanner
2023-10-11 17:12:59.471 17290-17376 ScanJob com.testble.mobile I Using immediateScanJobId from manifest: 208352939
2023-10-11 17:12:59.472 17290-17376 ScanJob com.testble.mobile I Running immediate scan job: instance is org.altbeacon.beacon.service.ScanJob@2147653
2023-10-11 17:12:59.478 17290-17376 ScanJob com.testble.mobile I scanJob version 2.20-beta1 is starting up on the main process
2023-10-11 17:12:59.507 17290-17376 ModelSpeci...Calculator com.testble.mobile W Cannot find match for this device. Using default
2023-10-11 17:12:59.508 17290-17376 ModelSpeci...Calculator com.testble.mobile W Cannot find match for this device. Using default
2023-10-11 17:12:59.512 17290-17376 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:12:59.540 17290-17377 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:12:59.541 17290-17376 ScanJob com.testble.mobile I Scan job running for 10000 millis
2023-10-11 17:12:59.548 17290-17305 BluetoothLeScanner com.testble.mobile D onScannerRegistered() - status=0 scannerId=3 mScannerId=0
2023-10-11 17:12:59.673 17290-17386 ScanHelper com.testble.mobile I Non-distinct packets detected in a single scan. Restarting scans unecessary.
2023-10-11 17:13:09.544 17290-17290 ScanJob com.testble.mobile I Scan job runtime expired: org.altbeacon.beacon.service.ScanJob@2147653
2023-10-11 17:13:09.559 17290-17290 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:13:09.575 17290-17377 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:13:09.747 17290-17290 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:13:10.202 17290-17290 ScanJob com.testble.mobile I Using immediateScanJobId from manifest: 208352939
2023-10-11 17:13:10.231 17290-17290 ScanJob com.testble.mobile I Using periodicScanJobId from manifest: 208352940
2023-10-11 17:13:10.231 17290-17290 JobInfo com.testble.mobile W Requested interval +5m10s0ms for job 208352940 is too small; raising to +15m0s0ms
2023-10-11 17:13:10.232 17290-17290 JobInfo com.testble.mobile W Requested flex 0 for job 208352940 is too small; raising to +5m0s0ms
2023-10-11 17:13:10.251 17290-17290 ScanJob com.testble.mobile I ScanJob Lifecycle START: org.altbeacon.beacon.service.ScanJob@bffaf41
2023-10-11 17:13:10.381 17290-17389 ScanHelper com.testble.mobile D BeaconParsers set to count: 2
2023-10-11 17:13:10.381 17290-17389 ScanHelper com.testble.mobile D First parser layout: m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25
2023-10-11 17:13:10.381 17290-17389 CycledLeScanner com.testble.mobile I Using Android O scanner
2023-10-11 17:13:10.390 17290-17389 ScanJob com.testble.mobile I Using immediateScanJobId from manifest: 208352939
2023-10-11 17:13:10.390 17290-17389 ScanJob com.testble.mobile I Running immediate scan job: instance is org.altbeacon.beacon.service.ScanJob@bffaf41
2023-10-11 17:13:10.395 17290-17389 ScanJob com.testble.mobile I scanJob version 2.20-beta1 is starting up on the main process
2023-10-11 17:13:10.405 17290-17391 ScanHelper com.testble.mobile I Non-distinct packets detected in a single scan. Restarting scans unecessary.
2023-10-11 17:13:10.425 17290-17389 ModelSpeci...Calculator com.testble.mobile W Cannot find match for this device. Using default
2023-10-11 17:13:10.426 17290-17389 ModelSpeci...Calculator com.testble.mobile W Cannot find match for this device. Using default
2023-10-11 17:13:10.433 17290-17389 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:13:10.466 17290-17390 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:13:10.466 17290-17389 ScanJob com.testble.mobile I Scan job running for 10000 millis
2023-10-11 17:13:10.472 17290-17304 BluetoothLeScanner com.testble.mobile D onScannerRegistered() - status=0 scannerId=3 mScannerId=0
2023-10-11 17:13:20.471 17290-17290 ScanJob com.testble.mobile I Scan job runtime expired: org.altbeacon.beacon.service.ScanJob@bffaf41
2023-10-11 17:13:20.483 17290-17290 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:13:20.501 17290-17390 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:13:20.635 17290-17290 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:13:21.591 17290-17290 ScanJob com.testble.mobile I Using immediateScanJobId from manifest: 208352939
2023-10-11 17:13:21.638 17290-17290 ScanJob com.testble.mobile I Using periodicScanJobId from manifest: 208352940
2023-10-11 17:13:21.639 17290-17290 JobInfo com.testble.mobile W Requested interval +5m10s0ms for job 208352940 is too small; raising to +15m0s0ms
2023-10-11 17:13:21.639 17290-17290 JobInfo com.testble.mobile W Requested flex 0 for job 208352940 is too small; raising to +5m0s0ms
2023-10-11 17:13:21.687 17290-17290 ScanJob com.testble.mobile I ScanJob Lifecycle START: org.altbeacon.beacon.service.ScanJob@d01a69f
2023-10-11 17:13:21.898 17290-17401 ScanHelper com.testble.mobile D BeaconParsers set to count: 2
2023-10-11 17:13:21.898 17290-17401 ScanHelper com.testble.mobile D First parser layout: m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24
2023-10-11 17:13:21.898 17290-17401 CycledLeScanner com.testble.mobile I Using Android O scanner
2023-10-11 17:13:21.909 17290-17401 ScanJob com.testble.mobile I Using immediateScanJobId from manifest: 208352939
2023-10-11 17:13:21.910 17290-17401 ScanJob com.testble.mobile I Running immediate scan job: instance is org.altbeacon.beacon.service.ScanJob@d01a69f
2023-10-11 17:13:21.915 17290-17401 ScanJob com.testble.mobile I scanJob version 2.20-beta1 is starting up on the main process
2023-10-11 17:13:21.948 17290-17401 ModelSpeci...Calculator com.testble.mobile W Cannot find match for this device. Using default
2023-10-11 17:13:21.949 17290-17401 ModelSpeci...Calculator com.testble.mobile W Cannot find match for this device. Using default
2023-10-11 17:13:21.955 17290-17401 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:13:21.991 17290-17401 ScanJob com.testble.mobile I Scan job running for 10000 millis
2023-10-11 17:13:21.992 17290-17402 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:13:21.997 9012-9032 BtGatt.GattService com.google.android.bluetooth E App 'com.testble.mobile' is scanning too frequently
2023-10-11 17:13:21.999 17290-17400 BluetoothLeScanner com.testble.mobile D onScannerRegistered() - status=6 scannerId=-1 mScannerId=0
2023-10-11 17:13:31.995 17290-17290 ScanJob com.testble.mobile I Scan job runtime expired: org.altbeacon.beacon.service.ScanJob@d01a69f
2023-10-11 17:13:32.014 17290-17290 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:13:32.032 17290-17402 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
2023-10-11 17:13:32.033 17290-17402 BluetoothLeScanner com.testble.mobile D could not find callback wrapper
2023-10-11 17:13:32.169 17290-17290 BluetoothAdapter com.testble.mobile D isLeEnabled(): ON
add shell ps). How does Logical look different when it fails?