I'm using Jetpack Compose to build an app that scans for BLE devices. Here's the composable that simply scans for BLE devices when it enters compostions and stops scanning when exiting. I have already obtained permissions of BLUETOOTH_CONNECT and BLUETOOTH_SCAN. The problem is, when the scan starts, nothing happened. The program didn't crash, but I can't find any BLE devices either. I noticed an error in logcat: "Bad call made by uid 1002. Package "top.frankyang.gc" does not belong to uid 1002.", is this related to the failure? How would I solve it or is there anything wrong in my code? I'm using Android 13 and my program targets Android 12.
// when this Composable enters composition, it's certain that we have the permission
@SuppressLint("MissingPermission")
@Composable
fun BleScanner(adapter: BluetoothAdapter) {
val scanner = adapter.bluetoothLeScanner
val devices = remember { mutableStateListOf<BluetoothDevice>() }
val callback = remember {
object : ScanCallback() {
override fun onScanResult(callbackType: Int, result: ScanResult) {
super.onScanResult(callbackType, result)
Log.i(TAG, "onScanResult: new device found: ${result.device}")
devices.add(result.device)
}
override fun onBatchScanResults(results: MutableList<ScanResult>) {
super.onBatchScanResults(results)
Log.i(TAG, "onBatchScanResults: new devices found: $results")
results.mapTo(devices) { it.device }
}
override fun onScanFailed(errorCode: Int) {
Log.w(TAG, "onScanFailed: scan failure: errorCode=$errorCode")
}
}
}
for (device in devices) {
Text(device.name)
}
if (devices.isEmpty()) {
Text(stringResource(R.string.no_device))
}
DisposableEffect(scanner) {
Log.i(TAG, "BleScanner: start scanning for BLE devices")
scanner.startScan(callback)
onDispose {
Log.i(TAG, "BleScanner: scanning stopped or adapter changed")
scanner.stopScan(callback)
}
}
}
2023-12-29 20:58:42.902 25173-25173 Bt top.frankyang.gc I BleScanner: scanning stopped or adapter changed
2023-12-29 20:58:42.903 25173-25173 BluetoothAdapter top.frankyang.gc D isLeEnabled(): ON
2023-12-29 20:58:42.906 25173-25173 BluetoothAdapter top.frankyang.gc D isLeEnabled(): ON
2023-12-29 20:58:43.862 25173-25173 Bt top.frankyang.gc I BleScanner: start scanning for BLE devices
2023-12-29 20:58:43.862 25173-25173 BluetoothAdapter top.frankyang.gc D isLeEnabled(): ON
2023-12-29 20:58:43.866 25173-4472 BluetoothLeScanner top.frankyang.gc D onScannerRegistered() - status=0 scannerId=8 mScannerId=0
2023-12-29 20:58:43.870 2489-4327 AppOps system_server E Bad call made by uid 1002. Package "top.frankyang.gc" does not belong to uid 1002.
Add android:usesPermissionFlags="neverForLocation" inside BLUETOOTH_SCAN permission declaration like this
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
Otherwise, the scanner will not give the result (or else you can declare location permissions in the Manifest.xml and turn on the device Location).
Doing so will give the scan result.
NB:
device.name
may lead to NPE