我用两个不同的命令进行了测试: 命令A:writeCharacteristic和设备响应什么都没有 命令B:使用onCharacteristicChanged的writeCharacteristic和设备响应
命令A可以正常工作,每个writeCharacteristic都可以成功 命令B不能正常工作,只有第一个writeCharacteristic可以成功,并且之后经常失败。
奇怪的是,当我在writeCharacteristic之前添加Thread.sleep(100)时,情况会稍好一些,延迟时间越长,失败的可能性就越低。我不知道这个问题的原因。
带有setupNotification的代码:
@Override
protected Observable<?> rxPrepare(final RxBleConnection connection) {
return connection
.discoverServices()
.flatMap(new Function<RxBleDeviceServices, SingleSource<BluetoothGattService>>() {
@Override
public SingleSource<BluetoothGattService> apply(RxBleDeviceServices rxBleDeviceServices) throws Exception {
return rxBleDeviceServices.getService(SERVICE_UUID);
}
})
.toObservable()
.flatMap(new Function<BluetoothGattService, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(BluetoothGattService bluetoothGattService) throws Exception {
mWriteCharacteristic = bluetoothGattService.getCharacteristic(WRITE_CHARACTERISTIC_UUID);
if (mWriteCharacteristic == null) {
throw new BleCharacteristicNotFoundException(WRITE_CHARACTERISTIC_UUID);
}
final BluetoothGattCharacteristic notifyCharacteristic = bluetoothGattService.getCharacteristic(NOTIFY_CHARACTERISTIC_UUID);
if (notifyCharacteristic == null) {
throw new BleCharacteristicNotFoundException(NOTIFY_CHARACTERISTIC_UUID);
}
return connection.setupNotification(notifyCharacteristic, NotificationSetupMode.DEFAULT)
.doOnNext(new Consumer<Observable<byte[]>>() {
@Override
public void accept(Observable<byte[]> observable) throws Exception {
doListenCharacteristicChanged(observable);
}
});
}
})
.retryWhen(new RetryWithDelay(1000, 3, new Predicate<Throwable>() {
@Override
public boolean test(Throwable throwable) throws Exception {
return mBluetoothAdapter != null && mBluetoothAdapter.isEnabled();
}
}));
}
@SuppressLint("CheckResult")
private void doListenCharacteristicChanged(Observable<byte[]> observable) {
observable
.subscribe(new Consumer<byte[]>() {
@Override
public void accept(byte[] bytes) throws Exception {
onReceiveData(bytes);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.e(TAG, "throwable:" + throwable + " Thread:" + Thread.currentThread().getName());
}
});
}
带有发送命令的代码:
public boolean sendDataSync(@NonNull byte[] data) {
RxBleConnection connection = getRxBleConnection();
if (!isConnected() || connection == null || mWriteCharacteristic == null) {
return false;
} else {
if (WristbandApplication.isDebugEnable())
Log.e(TAG, "Send Data :" + BytesUtil.byte2HexStr(data));
boolean success = true;
try {
//Thread.sleep(100);
if (data.length <= MTU_SIZE) {
connection.writeCharacteristic(mWriteCharacteristic, data).blockingGet();
} else {
RxBleConnection.LongWriteOperationBuilder builder = connection.createNewLongWriteBuilder();
builder.setBytes(data);
builder.setCharacteristic(mWriteCharacteristic);
builder.setMaxBatchSize(MTU_SIZE);
builder.build().blockingSubscribe();
}
} catch (Exception e) {
e.printStackTrace();
success = false;
}
return success;
}
}
测试代码:
public void set_user_info() {
boolean success = mWristManager.sendDataSync(datas);
Log.e(TAG, "sendDataSync result:" + success);
success = mWristManager.sendDataSync(datas);
Log.e(TAG, "sendDataSync result:" + success);
success = mWristManager.sendDataSync(datas);
Log.e(TAG, "sendDataSync result:" + success);
success = mWristManager.sendDataSync(datas);
Log.e(TAG, "sendDataSync result:" + success);
success = mWristManager.sendDataSync(datas);
Log.e(TAG, "sendDataSync result:" + success);
}
错误:
com.polidea.rxandroidble2.exceptions.BleGattCannotStartException: GATT exception from MAC address 10:00:A1:12:09:AC, with type BleGattOperation{description='CHARACTERISTIC_LONG_WRITE'}
at com.polidea.rxandroidble2.internal.operations.CharacteristicLongWriteOperation.writeData(CharacteristicLongWriteOperation.java:177)
at com.polidea.rxandroidble2.internal.operations.CharacteristicLongWriteOperation.access$200(CharacteristicLongWriteOperation.java:44)
at com.polidea.rxandroidble2.internal.operations.CharacteristicLongWriteOperation$2.subscribe(CharacteristicLongWriteOperation.java:155)
at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)
at io.reactivex.Observable.subscribe(Observable.java:12051)
at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38)
at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:762)