Skip to content
Advertisement

Bluetooth LE – How to set custom scan delay?

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:-

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement