几天后,我尝试在我的 APP 中实现 BLE 连接。我知道我尝试连接的设备功能齐全,所以问题一定出在我的代码上。
我使用 BluetoothLeScanner.startScan()
方法。
但是永远不会调用回调方法。
public void startScan() {
if (bluetoothAdapter != null && bluetoothAdapter.isEnabled()) {
isScanning = true;
Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mainActivityHandler.setMSG("Scan stopped");
isScanning = false;
leScanner.stopScan(scanCallback);
}
}, SCAN_TIME);
mainActivityHandler.setMSG("Start scan");
try {
leScanner.startScan(scanCallback);
} catch (Exception e) {
mainActivityHandler.catchError(e);
}
} else mainActivityHandler.catchError(new Exception("Bluetooth not activated"));
}
我的 CallbackMethod(不知道我是否正确使用 gatt,但这是另一个问题):
private ScanCallback scanCallback = new ScanCallback() {
@Override
public void onBatchScanResults(List<ScanResult> results) {
mainActivityHandler.setMSG("Callback");
isScanning = false;
try {
mainActivityHandler.setMSG("Connected to " + results.get(0).getDevice().getName());
gatt = results.get(0).getDevice().connectGatt(mainActivity, true, bluetoothGattCallback);
BluetoothGattDescriptor descriptor;
for (int i = 0; i < charIDs.length; i++) {
gatt.setCharacteristicNotification(gatt.getService(serviceID[0]).getCharacteristic(charIDs[i]), true);
descriptor = gatt.getService(serviceID[0]).getCharacteristic(charIDs[0]).getDescriptor(charIDs[i]);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);
}
} catch (Exception e) {
mainActivityHandler.catchError(e);
}
}
};
最佳答案
问题
问题是您只是覆盖了 onBatchScanResults
方法,而不是 onScanResult
方法。 onBatchScanResults
只有在以下情况下才会被触发:
- 您已使用
ScanSettings.Builder
将ScanSettings
模式设置为ScanSettings.SCAN_MODE_LOW_POWER
(这是默认设置)。 - 您已在
ScanSettings.Builder
中使用setReportDelay(long reportDelayMillis)
将报告延迟时间设置为某个值 >0。
reportDelayMillis - Delay of report in milliseconds. Set to 0 to be notified of results immediately. Values > 0 causes the scan results to be queued up and delivered after the requested delay or when the internal buffers fill up.
例如:
public void startScan(BluetoothLeScanner scanner) {
ScanFilter filter = new ScanFilter.Builder().setDeviceName(null).build();
ArrayList<ScanFilter> filters = new ArrayList<ScanFilter>();
filters.add(filter);
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
.setReportDelay(1l)
.build();
Log.i(TAG,"The setting are "+settings.getReportDelayMillis());
scanner.startScan(filters,settings,BLEScan);
}
解决方案
但是,您可能只想一次获得结果而不是一批结果。为此,您不必修改 ScanSettings,只需重写 ScanCallback
中的 onScanResult
方法即可。
private ScanCallback mScanCallback =
new ScanCallback() {
public void onScanResult(int callbackType, ScanResult result) {
System.out.println(result.getDevice().getName())
// Do whatever you want
};
...
};
替代方案 - RxAndroidBle
无论如何,我强烈推荐使用库 RxAndroidBle .它维护得很好,它解决了许多开箱即用的 BLE 问题(扫描可能是 BLE 中不太复杂的部分)。
使用该库,扫描可以像这样完成:
Disposable scanSubscription = rxBleClient.scanBleDevices(
new ScanSettings.Builder()
// .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // change if needed
// .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) // change if needed
.build()
// add filters if needed
)
.subscribe(
scanResult -> {
// Process scan result here.
},
throwable -> {
// Handle an error here.
}
);
// When done, just dispose.
scanSubscription.dispose();
关于Android BLE Scan 永远找不到设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53829479/