Android BLE扫描ScanCallback如何实现指定间隔未发现设备的回调
实现方案
核心逻辑
你需要的超时清空逻辑属于业务层的控制逻辑,BLE扫描框架本身没有提供原生回调属于合理情况,我们可以通过Android官方标准API实现,完全符合规范,不属于变通方案:
每次收到扫描结果回调时,取消之前待触发的清空列表任务,重新提交一个延时指定间隔的清空任务。只要在间隔内有新的扫描结果到达,清空任务就会被持续推后;一旦超过间隔未收到任何扫描结果,延时任务就会正常触发执行列表清空操作。
协程实现(推荐,适配现代Android开发规范)
前置准备
首先声明两个成员变量,和扫描逻辑的生命周期绑定:
// 自定义超时间隔,示例为5秒 private val SCAN_TIMEOUT_MS = 5000L // 存储待执行的清空任务 private var clearDevicesJob: Job? = null // 你自己的设备列表实现,这里仅作示例 private val foundDevices = mutableListOf<BluetoothDevice>()
修改ScanCallback实现
private val leScanCallback: ScanCallback = object : ScanCallback() { override fun onScanResult(callbackType: Int, result: ScanResult) { super.onScanResult(callbackType, result) val device = result.device Log.d("LeDeviceScanner", "Device found: ${device.address} - ${device.name ?: "Unknown"}") onDeviceResult(result.device) // 核心逻辑:收到扫描结果后重置超时任务 clearDevicesJob?.cancel() clearDevicesJob = lifecycleScope.launch { // 这里可以用和页面/扫描生命周期绑定的Scope,比如viewModelScope delay(SCAN_TIMEOUT_MS) // 超时未收到扫描结果,清空列表 foundDevices.clear() // 这里可以加你自己的列表更新通知逻辑,比如notifyDataSetChanged } } override fun onScanFailed(errorCode: Int) { super.onScanFailed(errorCode) // 扫描失败时也可以按需取消超时任务、清空列表 clearDevicesJob?.cancel() foundDevices.clear() } }
生命周期适配
- 启动扫描时,可主动提交一次超时任务,避免启动后长期未扫描到设备时列表不会清空
- 停止扫描时,主动调用
clearDevicesJob?.cancel()取消待执行任务,避免内存泄漏和不必要的逻辑触发
Handler实现(兼容旧项目无协程的场景)
前置准备
private val SCAN_TIMEOUT_MS = 5000L private val mainHandler = Handler(Looper.getMainLooper()) private val foundDevices = mutableListOf<BluetoothDevice>() private val clearDevicesRunnable = Runnable { foundDevices.clear() // 列表更新通知逻辑 }
修改ScanCallback实现
private val leScanCallback: ScanCallback = object : ScanCallback() { override fun onScanResult(callbackType: Int, result: ScanResult) { super.onScanResult(callbackType, result) val device = result.device Log.d("LeDeviceScanner", "Device found: ${device.address} - ${device.name ?: "Unknown"}") onDeviceResult(result.device) mainHandler.removeCallbacks(clearDevicesRunnable) mainHandler.postDelayed(clearDevicesRunnable, SCAN_TIMEOUT_MS) } override fun onScanFailed(errorCode: Int) { super.onScanFailed(errorCode) mainHandler.removeCallbacks(clearDevicesRunnable) foundDevices.clear() } }
生命周期适配
和协程实现一致,启动扫描时按需调用postDelayed,停止扫描时调用removeCallbacks释放资源。
内容的提问来源于stack exchange,提问作者user16627306
相关产品推荐
相关产品推荐

