I am making an app to scan all tags using Bluetooth LE. I have to implement a interval feature where an user can enter seconds for scan delay, but i have not found any method to do so. I tried implementing TimerTask but it still scans more than one device in a second Is there any way to implement a interval such as scanning one tag every second or more?
My code:
class BluetoothActivity : AppCompatActivity(), MenuProvider{
private lateinit var recyclerView: RecyclerView
private var bluetoothLeScanner: BluetoothLeScanner? = null
private val deviceList = mutableListOf<BleTag>()
private val deviceMap = mutableMapOf<String, BleTag>()
private var interval: Long = 0
private lateinit var menu: Menu
private lateinit var tagBinding: ListbluethoothBinding
val before = DateFormat.getDateTimeInstance().format(Date(System.currentTimeMillis()))
private val scanCallback = object : ScanCallback(){
@RequiresApi(Build.VERSION_CODES.N)
@SuppressLint("MissingPermission", "NotifyDataSetChanged")
override fun onScanResult(callbackType: Int, result: ScanResult) {
val scanJob = CoroutineScope(Dispatchers.Main).launch {
val tag = deviceMap.computeIfAbsent(result.device.address) {
val newTag = BleTag(result.device.name ?: "Unbekannt", result.device.address, result.rssi , result.scanRecord?.bytes, "")
deviceList.add(newTag)
newTag
}
tag.name = result.device.name ?: "Unbekannt"
tag.rssi = result.rssi
tag.advertisementData = result.scanRecord?.bytes
}
deviceList.sortBy {result.rssi }
menu.findItem(R.id.count).title = "Geräte: " deviceList.size
super.onScanResult(callbackType, result)
}
override fun onScanFailed(errorCode: Int) {
super.onScanFailed(errorCode)
Log.e("Scan failed","")
}
}
@SuppressLint("MissingPermission")
@RequiresApi(Build.VERSION_CODES.M)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
tagBinding = ListbluethoothBinding.inflate(layoutInflater)
val view = tagBinding.root
setContentView(view)
recyclerView = tagBinding.list
val layoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = layoutManager
recyclerView.adapter = RecyclerViewAdapter(deviceList)
addMenuProvider(this)
val bluetoothManager: BluetoothManager = getSystemService(BluetoothManager::class.java)
val bluetoothAdapter: BluetoothAdapter? = bluetoothManager.adapter
bluetoothLeScanner = bluetoothAdapter?.bluetoothLeScanner
interval = getSharedPreferences("interval", MODE_PRIVATE).getLong("interval", 1000)
bluetoothLeScanner!!.startScan(scanCallback)
}
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
[email protected] = menu
menuInflater.inflate(R.menu.items, menu)
}
@RequiresApi(Build.VERSION_CODES.M)
@SuppressLint("MissingPermission")
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
when(menuItem.itemId) {
R.id.stop -> {
bluetoothLeScanner!!.stopScan(scanCallback)
Snackbar.make(findViewById(android.R.id.content),"Scan gestoppt", 2000).show()
}
R.id.start -> {
bluetoothLeScanner!!.startScan(scanCallback)
Snackbar.make(findViewById(android.R.id.content),"Scan gestartet", 2000).show()
}
}
return true
}
}
CodePudding user response:
Unfortunately Android does not give you this granularity, and the values are set in the source code as can be seen here. In terms of setting it via an API, the only thing you can do is set SCAN_MODE_LOW_LATENCY via the ScanSettings class.
Some people have found a few workarounds around this which you can find in the links below:-