connection.writeCharacteristic failed when onCharacteristicChanged has callback
See original GitHub issueI have test with two diffrent command: command A : writeCharacteristic and device response nothing command B : writeCharacteristic and device response something with onCharacteristicChanged
Command A can work properly, every writeCharacteristic can succeed Command B does not work properly, only the first writeCharacteristic can succeed, and often fails afterwards.
And the strange thing is that when I added a Thread.sleep(100) before the writeCharacteristic, the situation will be slightly better, the longer the delay, the lower the probability of failure. I don’t know the cause of this problem.
code with 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());
}
});
}
code with send command:
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;
}
}
test code:
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);
}
error:
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)
Issue Analytics
- State:
- Created 5 years ago
- Comments:10 (5 by maintainers)
Top Results From Across the Web
connection.writeCharacteristic failed when ... - GitHub
I have test with two diffrent command: command A : writeCharacteristic and device response nothing command B : writeCharacteristic and ...
Read more >java - Android BLE: onDescriptorWrite, onCharacteristicWrite ...
I am calling them one at a time. The test code I've built does nothing but call writeCharacteristic after the connection is made,...
Read more >BluetoothGattCallback - Android Developers
Use BluetoothGattCallback#onCharacteristicChanged(BluetoothGatt, ... Callback indicating the MTU for a given device connection has changed.
Read more >Making Android BLE work — part 3 - Medium
This means that the command you issue will return immediately and you will receive the data a bit later via a callback function....
Read more >Bluetooth LE not triggering OnCharacteristicWrite - MSDN
My BluetoothGattCallback is as follows: ... As such, subsequent calls to WriteCharacteristic fail. Below is a list of what I have tried (and ......
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Hello!
Thank you for using the library.
This is a general usage question and as such should be posted on stackoverflow with
rxandroidble
tag—it will be easier to find by other users.Best Regards
Great, thanks for you help.