I’m developing an Android app that scans for iBeacon devices using the AltBeacon library. The app works perfectly on Android 11 and below, successfully detecting iBeacon devices. However, on Android 12 and above, the app fails to detect any iBeacon devices.
Despite setting everything up, the app detects no iBeacons on devices running Android 12 or higher (tested on Samsung A52 with Android 13 and Google Pixel 6 with Android 14).
What I’ve Tried:
- I have added all the necessary permissions in the
AndroidManifest.xml
file, including the new Android 12+ specific permissions (BLUETOOTH_SCAN
,BLUETOOTH_CONNECT
,POST_NOTIFICATIONS
) - I disabled ScanJobs in favor of a foreground scanning service
- I ensured that Bluetooth was enabled, and the location was active during the scan
- I implemented the
BeaconParser
with the correct layout and have overridden the required methods (didRangeBeaconsInRegion
,didEnterRegion
,didExitRegion
, etc.)
Manifest File:
Here is my AndroidManifest.xml
:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" >
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-feature android:name="android.hardware.bluetooth" android:required="true" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/Theme.MyApp" tools:targetApi="tiramisu" >
<activity android:name=".MainActivity" android:exported="true" android:theme="@style/Theme.MyApp" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="org.altbeacon.beacon.service.ScanJob" android:permission="android.permission.BIND_JOB_SERVICE" />
<meta-data android:name="android.app.job.JobScheduler.SCHEDULE_IMMEDIATE" android:value="true" />
</application></manifest>
Relevant Code:
- Below is the relevant part of the code where I set up and start the iBeacon scanning:
class BluetoothServices(private val activity: AppCompatActivity): RangeNotifier, MonitorNotifier {
private var beaconManager: BeaconManager = BeaconManager.getInstanceForApplication(activity)
private val devicesFound = mutableListOf<IBeacon>()
private val myIBeaconsRegion: Region = Region("myUniqueBeaconRegion", Identifier.parse(bleUUID), null, null)
init {
beaconManager.beaconParsers.add(BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"))
beaconManager.foregroundScanPeriod = 1100L
beaconManager.foregroundBetweenScanPeriod = 0L
beaconManager.setEnableScheduledScanJobs(false)
beaconManager.enableForegroundServiceScanning(createNotification(), NOTIFICATION_ID)
beaconManager.addMonitorNotifier(this)
beaconManager.addRangeNotifier(this)
}
fun startBluetoothScan() {
if (managerDevices.areBluetoothPermissionsGranted() && managerDevices.isBluetoothEnabled() && managerDevices.isLocationActive()) {
try {
beaconManager.startMonitoring(myIBeaconsRegion)
beaconManager.startRangingBeacons(myIBeaconsRegion)
beaconManager.requestStateForRegion(myIBeaconsRegion)
} catch (e: RemoteException) {
e.printStackTrace()
}
}
}
override fun didRangeBeaconsInRegion(beacons: MutableCollection<Beacon>?, region: Region?) {
beacons?.forEach { beacon ->
if (isPointer(beacon.id1)) {
val iBeacon = IBeacon(beacon.bluetoothAddress)
iBeacon.uuid = beacon.id1.toString()
iBeacon.major = beacon.id2.toInt()
iBeacon.minor = beacon.id3.toInt()
iBeacon.rssi = beacon.rssi
iBeacon.manufacturer = beacon.manufacturer.toString()
devicesFound.add(iBeacon)
iBeaconsView.updateListIBeacons(devicesFound)
}
}
}
// Other overridden methods (didEnterRegion, didExitRegion, etc.)
}
Logs:
- Here is a snippet from the log:
2024-08-04 13:06:05.215 27704-27704 BeaconManager com.gtdvm.echopoint
2024-08-04 13:06:05.222 27704-27704 BackgroundPowerSaver
com.gtdvm.echopoint
I Background mode not set. We assume we are in the foreground.
2024-08-04 13:06:05.245 27704-27704 ScanHelper
com.gtdvm.echopoint D BeaconParsers set to count: 0
2024-08-04 13:06:05.314 27704-27724 BluetoothLeScanner
com.gtdvm.echopoint D onScannerRegistered() - status=0 scannerId=2 mScannerId=0
NOTE:
– Notification and foreground services delay on Android 13/14 (2/3 seconds) compared to Instant start on Android 11 on first run (when I start scan, when I press scan button) and if I stop scan and start then immediately process scan works. And if I close the application and reopen after 2/3 minutes, it’s still the same problem, delay.