Android 4.3: How to connect to multiple Bluetooth Low Energy devices
I suspect everyone adding delays is just allowing the BLE system to complete the action you have asked before you submit another one. Android's BLE system has no form of queueing. If you do
BluetoothGatt g;
g.writeDescriptor(a);
g.writeDescriptor(b);
then the first write operation will immediately be overwritten with the second one. Yes it's really stupid and the documentation should probably actually mention this.
If you insert a wait, it allows the first operation to complete before doing the second. That is a huge ugly hack though. A better solution is to implement your own queue (like Google should have). Fortunately Nordic have released one for us.
https://github.com/NordicSemiconductor/puck-central-android/tree/master/PuckCentral/app/src/main/java/no/nordicsemi/puckcentral/bluetooth/gatt
Edit: By the way this is the universal behaviour for BLE APIs. WebBluetooth behaves the same way (but Javascript does make it easier to use), and I believe iOS's BLE API also behaves the same.
How to connect multiple BLE devices at the same time in android app
It's very simple. Just execute connectGatt one time for every device, which will then give you one BluetoothGatt object per device. The callback object can be the same, or a separate instance per device, it's up to you, although I guess it's easier if you have one instance per device.
Handling Notifications on Android with Multiple BLE Peripheral Connections
It seems that BLE on Android cannot handle sampling rates at 50Hz and higher. I am not sure if this is a BLE-related problem or if it has something to do with the onCharacteristicCHanged
method being called too frequently. I solved this by sending larger packets of data every 50ms, contrary to my original case at every 20ms. Larger BLE data packets are possible starting from Bluetooth 4.2, which is controlled using the MTU, Maximum Throughput Unit. This blog helped me a lot in understanding the underlying mechanism.
When receiving large packets of data over BLE at high sampling rates, it is best to use gatt.requestMtu(MY_DESIRED_MTU)
with MY_DESIRED_MTU > 20Bytes
inside the corresponding BluetoothGattCallback
on Android. It should be noted that larger MTU means it takes longer for the data to be written on the BLE characteristic for the server device.
In short, I am using larger data packets and a larger delay to make up for the limitations in the sampling rate. For a sampling rate of 100Hz on the IMU in the T-Wristband, I am using an MTU of 95 Bytes, requested by the Android device, and a 50ms delay on the timer on the T-Wristband. This allows me to receive five consecutive data samples every 50ms.
How to list Bluetooth Low Energy devices on Android 4.3?
I forgot to add the BLUETOOTH_ADMIN
permission. Without this permission, one can still call startLeScan
,it just won't ever discover any devices!
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
Related Topics
Highlighting Text Color Using HTML.Fromhtml() in Android
How to Align Android Toolbar Menu/Icons to the Left Like in Google Maps App
Android Studio Project Structure (V.S. Eclipse Project Structure)
Using Build Types in Gradle to Run Same App That Uses Contentprovider on One Device
Android-L Cardview Visual Touch Feedback
Handlers, Messagequeue, Looper, Do They All Run on the UI Thread
Do I Need 14 Different Layouts to Support All Android Devices
Android Studio: New Project VS New Module
How to Extract Code of .Apk File Which Is Not Working
Tab Not Taking Full Width on Tablet Device [Using Android.Support.Design.Widget.Tablayout]
Fitssystemwindows Effect Gone for Fragments Added via Fragmenttransaction
Format Statement in a String Resource File
How to Create an Avd for Android 4.0
How to Manage Audio Volumes Sanely in My Android App
Get Battery Level Before Broadcast Receiver Responds for Intent.Action_Battery_Changed