Android:如何获取蓝牙扫描状态?BLE扫描时isScanning何时设为false?
BLE扫描状态
isScanning的正确设置方式 你问的这个问题很关键——状态同步不对很容易导致后续扫描操作出问题,我来给你详细说明:
什么时候要把isScanning设为false?
主要有三类场景必须更新这个状态:
- 主动停止扫描时(用户手动触发、达到预设扫描时长)
- 找到目标设备后自动停止扫描时
- 扫描失败或异常终止时
能不能在ScanCallback里实现?
当然可以!而且这是处理“找到目标就停扫”和“扫描失败”场景的最佳位置,我给你修改一下你的代码示例:
private volatile boolean isScanning = false; // 用volatile保证线程安全 private ScanCallback scanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, final ScanResult result) { super.onScanResult(callbackType, result); if(result==null) return; // 示例:找到目标设备后立即停止扫描并更新状态 if (isTargetDevice(result)) { // 这里替换成你判断目标设备的逻辑 if (bluetoothLeScanner != null && isScanning) { bluetoothLeScanner.stopScan(this); isScanning = false; } } runOnUiThread(new Runnable() { @Override public void run() { // 处理扫描结果的UI更新逻辑 } }); } @Override public void onScanFailed(int errorCode) { super.onScanFailed(errorCode); // 扫描失败(比如蓝牙关闭、权限不足)时必须更新状态 isScanning = false; // 这里可以添加错误提示逻辑,比如Toast告知用户扫描出错 } };
其他场景的状态处理
1. 定时停止扫描
如果你的扫描需要持续固定时长(比如10秒),可以在启动扫描时搭配Handler延迟停扫:
if(bluetoothLeScanner!=null && !isScanning) { bluetoothLeScanner.startScan(scanCallback); isScanning = true; // 10秒后自动停止扫描 new Handler(Looper.getMainLooper()).postDelayed(() -> { stopBleScan(); }, 10000); } // 封装统一的停止扫描方法 private void stopBleScan() { if (bluetoothLeScanner != null && isScanning) { bluetoothLeScanner.stopScan(scanCallback); isScanning = false; } }
2. 用户主动停止扫描
比如用户点击“停止扫描”按钮时,直接调用上面的stopBleScan()方法即可,保证状态和扫描动作同步。
额外提醒
- 一定要用
volatile修饰isScanning,因为ScanCallback的回调是在后台线程执行的,而UI线程可能会读取这个变量,volatile能保证多线程下的状态可见性 - 每次启动扫描前先检查
isScanning的状态,避免重复调用startScan导致异常
内容的提问来源于stack exchange,提问作者Saravanabalagi Ramachandran
相关产品推荐
相关产品推荐

