在我的应用程序中我有启动和停止按钮,当用户按下启动时我调用startScan方法
bluetoothAdapter.getBluetoothLeScanner().startScan(getLeScanCallback());
当用户按下停止时,我会调用stopScan,但它似乎什么也没做。 BluetoothAdapter会持续扫描新设备。
bluetoothAdapter.getBluetoothLeScanner().stopScan(getLeScanCallback());
这是我的getLeScanCallback方法:
private ScanCallback getLeScanCallback(){
ScanCallback leScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
boolean duplicate = false;
for(Device d : devices) {
if(d.getAddress().equals(result.getDevice().getAddress()))
duplicate = true;
}
if(!duplicate) {
Device device = new Device();
device.setName(result.getDevice().getName());
device.setAddress(result.getDevice().getAddress());
device.setStatus(getString(R.string.disconnected));
devices.add(device);
deviceListAdapter.notifyDataSetChanged();
}
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
super.onBatchScanResults(results);
}
@Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
}
};
return leScanCallback;
}
即使在调用stopScan()之后它也会被调用。我做错了什么,换句话说,如何停止扫描BLE设备?
每次调用getLeScanCallback
时,都会创建ScanCallback
的新实例并丢失对前一个实例的引用。
stopScan
停止正在进行的扫描,无论你传递什么实例但是如果它是一个不同的实例(比你曾经开始的那个实例)它将不会删除旧的回调实例,所以仍然有一些事件会在它停止之前传递给它。
扫描结果不会立即停止,但最终会停止。有一个待处理结果的队列,您可以刷新:
scanner.flushPendingScanResults();
但即使这样,文档也很清楚,它会将它发现的任何内容发送给回调。即使您已停止扫描,也会发生这种情况。 API设计不佳,但它就是这样。
我认为最简单的方法是设置一个标志,以便在停止扫描后忽略扫描结果。
我没有注意到你的代码有任何问题,似乎没问题。也许你的getLeScanCallback()
方法存在问题?
您可以将它声明为成员变量,而不是让方法返回您的ScanCallback,因此您可以使用leScanCallback = new ScanCallback()
,然后在尝试停止扫描时可以引用此成员变量。
bluetoothAdapter.getBluetoothLeScanner().stopScan(leScanCallback);
根据您支持的Android版本,可能值得添加Rajesh Panchal为Lollipop Android设备提供的startLeScan
和stopLeScan
方法。
更换
bluetoothAdapter.getBluetoothLeScanner().startScan(getLeScanCallback());
bluetoothAdapter.getBluetoothLeScanner().stopScan(getLeScanCallback());
同
bluetoothAdapter.getBluetoothLeScanner().startLeScan(getLeScanCallback());
bluetoothAdapter.getBluetoothLeScanner().stopLeScan(getLeScanCallback());