I am creating an app which periodically (let's assume every 5 seconds), through a ble scan, shows the user on the screen the number of devices around him. We also assume that the user has accepted all permissions.
This is an example of the code:
class ExampleBle(private val viewModel: Mainviewmodel) {
private val deviceAddresses = arrayListOf<String>()
private val bleAdapter: BluetoothAdapter by lazy {
val b = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
b.adapter
}
private val bleScan : BluetoothLeScanner by lazy {
bleAdapter.bluetoothLeScanner
}
private val scanSettings = ScanSettings.Builder()
//Questo tipo di scan è usato per scan di lunga durata e spreca meno energia
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build()
private val scanCallback = object : ScanCallback() {
@SuppressLint("MissingPermission")
override fun onScanResult(callbackType: Int, result: ScanResult) {
deviceAddresses.add(result.device.address)
}
override fun onScanFailed(errorCode: Int) {
Log.e("ScanCallback", "onScanFailed: code $errorCode")
}
}
//function to repeat every 5 seconds
fun startScan(){
bleScan.startScan(null, scanSettings, scanCallback)
// at this point the deviceAddresses list contains the addresses
// of all the devices around
viewModel.updateNumberDevices(deviceAddresses.size)
//clear the list to recollect all the device addresses from the next scan after 5 seconds
deviceAddresses.clear()
}
}
So basically, if there are 10 devices around the user: startScan() -> bleScan.startScan() -> scanCallBack -> {deviceAddresses.add(result.device1.address)} . . . -> scanCallBack -> {deviceAddresses.add(result.device10.address)}
Is the code consistent with what I would like to achieve? I also have some doubts:
I hope I have explained myself well, and that I have not given an example too "rough". I would just like to understand in a very direct and basic way how the ble scan works on a more practical level.
The code looks mostly consistent with what you are trying to achieve. The main things missing are the printing of the scanned devices and the handling of the scan stop callback, but I'm guessing that both these things are done elsewhere. As to your other questions:-
"If there are many devices around (100 for example), would the scan be able to return all the addresses in 5 seconds?"
This depends on many variables such as the environment, your scan parameters, and the parameters that the other devices are advertising in. Assuming that all other devices are advertising at the maximum rate (20ms), then theoretically you can read 100 device adverts in 2 seconds. However, in reality the number will probably much lower due to the other variables. I think 5 seconds is a good duration for most applications but if you want a bigger chance of capturing all devices in the vicinity, maybe increase the scan duration to 10 seconds.
"If It doesn't succeed and I start the bleStartScan function before the previous one has finished, would I have some irregularities in the list that I'm updating (such as duplicate addresses etc..)?"
You shouldn't be able to start a new scan function before the previous one has finished. You will get an error telling you that a scan is already in progress.
In my opinion, the best way to understand these things is to do exactly what you are doing:- try out a practical example and also do some reading in the background. I think the following links are very good guides on getting started with Android and BLE:-