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) { MainActivity@this.menu = 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 } }
Advertisement
Answer
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:-