Support connectGatt of API level 26 to pass handler to use for callback to notify/write on single characteristic
Do you have a plan to pass my handler to connectGatt of API level 26 to use for callback?
I think that SweetBLUE does not support it but I want to avoid thread safety problem of BluetoothGattCharacteristic as written on How could I achieve maximum thread safety with a read/write BLE Gatt Characteristic?.
If the latest SweetBLUE already support to write to and be notified from a single characteristic, please notice it.
I think that the latest android bluetooth framework still have the following issues, and I expect that SweetBLUE can avoid it.
- Writing and notifying from the same characteristic
- Generally there is no such issue but you shouldn't do it if you intend to communicate with an Android phone since there is a race condition in the API itself
- So I would definitely recommend you to have two characteristics.
- How could I achieve maximum thread safety with a read/write BLE Gatt Characteristic?
- This change allows us to force all calls to BluetoothGattCharacteristic.setValue() - both for our outbound writing to the characteristic and the inbound notifications - onto the same thread, which eliminates the race condition corrupting the BluetoothGattCharacteristic.mValue;
- Writing and notifying from the same characteristic
Thread safety is not something you need to worry about with SweetBlue. The library has its own set of interfaces for listening for responses/states. All BLE calls made from the library are done on the same thread, and all callbacks are done on the main/UI thread (this is configurable). https://sweetblue.io/docs/Getting-Started will show you how to scan for devices, connect to a device, and how to read a characteristic.
SweetBlue will allow you to enable notifications on any characteristic that supports it, regardless if you write to it or not.
Hope this helps.
@ryanbis Thanks a lot for your reply.
All BLE calls made from the library are done on the same thread, and all callbacks are done on the main/UI thread (this is configurable).
OK, but we faced the thread safety problem that value in single BluetoothGattCharacteristic was broken if writing data to it and notified from device frequently.
It means that the problem is caused by calling library function write() on another thread than main/UI's one, and the problem can be fixed if we call the library functions on main/UI thread, doesn't it?
all callbacks are done on the main/UI thread (this is configurable).
I didn't know it's configurable... For my study, please teach me how to configure it. Is the document I should refer to the following?
If you want to change what thread SweetBlue makes its calls on, you set the option
updateThreadTypein BleManagerConfig. If you want it all done on the main thread, then set it to UpdateThreadType.MAIN. You only need to deal with the
updateHandleroption if you want to run SweetBlue logic on your own thread.
@ryanbis Thanks for your reply and advice. I want to confirm one more point. Does the
UpdateThreadType.MAINoption hand over the main thread handler to
BluetoothDevice.connectGatt()? If not, I want to know how to hand over the main thread handler to
BleDevice.connect()to avoid the below issue.
we faced the thread safety problem that value in single BluetoothGattCharacteristic was broken if writing data to it and notified from device frequently.
I guess that this issue can be avoided by handing over the main thread handler to
BluetoothDevice.connectGatt()according to BluetoothGatt.onNotify() and BluetoothGatt.runOrQueueCallback() implementation.
According to your advice, I tried to use
UpdateThreadType.MAIN, and it seems that
P_TaskManagerworks on TID 27305 which is same as main/UI's TID, but
onCharacteristicChanged()seems to run on another TID 31185 as the below log. My expectation was that
onCharacteristicChanged()also runs on TID 27305.
09-28 15:46:03.639 27305 27305 I PA_Task : MAIN(27305) setState() - Write(SUCCEEDED core_C76A e7add780-b042-4876-aae1-112855353cc1 txn==null 81741537 ) - 35815 09-28 15:46:03.639 27305 27305 I P_TaskManager: MAIN(27305) print() - no current task  09-28 15:46:03.649 1370 1872 I bt_stack: [INFO:gatt_main.cc(919)] gatt_data_process op_code = 27, msg_len = 8 09-28 15:46:03.650 1370 1872 E bt_btif : bta_gattc_process_indicate, ignore HID ind/notificiation 09-28 15:46:03.651 27305 31185 D P_BleDevice_ListenerProcessor [Native]: FAY(31185) onCharacteristicChanged() [14:B4:57:CD:C7:6A] - characteristic=e7add780-b042-4876-aae1-112855353cc1
Ahh ok, I got you. You could just connect the gatt manually by using the underlying android instances. On the BleDevice, call
bleDevice.getNative().getNativeDevice();. This will return the BluetoothDevice instance, and you can call connectGatt yourself. Then, you'll have to implement your own BluetoothGattCallback. But doing this means you're not really using the library anymore. I'll do my best to get an update out which utilizes this method.
I'll do my best to get an update out which utilizes this method.
Thank you for considering update! I hope it.
This will return the BluetoothDevice instance, ...
But doing this means you're not really using the library anymore.
Your SweetBLUE library is very helpful for us, so I want to enable both of your library functions and
connectGattwith thread handler.
I'm looking forward to support it.
@ryanbis Can I get an approx. ETA when you can provide an update on this (likely SweetBLUE new version release)?
We'd like to keep using your reliable SweetBLUE library with any solution of this thread safety problem rather than pursuing our own implementation on native Android.
NOTE: Our app supports only API level 26 or higher, so discard of API level 25 or lower works for us.
Can I get an approx. ETA when you can provide an update on this (likely SweetBLUE new version release)? We'd like to keep using your reliable SweetBLUE library with any solution of this thread safety problem rather than pursuing our own implementation on native Android.
Can I get an approx. ETA? In this year or next year, or...
Looks like it's going to be after thanksgiving. I've got it mostly working, but in order to support this, some threading changes have to happen, and more testing needs to happen before releasing it.
@ryanbis Thank you for your information. I'm glad to hear the progress.
From your comment, it seems difficult to release in this year. Is it likely to be released early next year?
3.2.7 was released, which does what you want. You will have to set the UpdateThreadType to HANDLER_THREAD. When using this thread type, SweetBlue will automatically pass the Handler to the connectGatt call, so that callbacks happen on the SweetBlue thread, instead of any random background thread.
@ryanbis I'm very glad 3.2.7 is released! Thank you for your prompt service. We are now verifying notify/write on single characteristic with setting UpdateThreadType as HANDLER_THREAD.