The bumpy road of BLE on Android LightBlue Bean BeanLoader for OS X LightBlue for iOS BeanLoader of iOS BeanLoader for Windows (2015) SDK for OS X and iOS 5
The bumpy road of BLE on Android LightBlue Bean BeanLoader for OS X LightBlue for iOS BeanLoader of iOS BeanLoader for Windows (2015) SDK for OS X and iOS 5
The bumpy road of BLE on Android 9 Bluetooth Low Energy Branded: Bluetooth Smart Low power, low transmission rate (1 Mbps) Sports & fitness, health care, keyboards and mice, beacons, wearables, …
The bumpy road of BLE on Android 12 UUIDs Unique identifier for services, characteristics (and descriptors) Profile a495ff10-c5b1-4b44-b512-1370f02d74de a495ff11-c5b1-4b44-b512-1370f02d74de 0000180F-0000-1000-8000-00805F9B34FB Reserved base UUID 00002A19-0000-1000-8000-00805F9B34FB
The bumpy road of BLE on Android 12 UUIDs Unique identifier for services, characteristics (and descriptors) Profile a495ff10-c5b1-4b44-b512-1370f02d74de a495ff11-c5b1-4b44-b512-1370f02d74de Reserved base UUID 0000180F-0000-1000-8000-00805F9B34FB 00002A19-0000-1000-8000-00805F9B34FB
The bumpy road of BLE on Android 12 UUIDs Unique identifier for services, characteristics (and descriptors) Profile a495ff10-c5b1-4b44-b512-1370f02d74de a495ff11-c5b1-4b44-b512-1370f02d74de Reserved base UUID 180F 2A19
The bumpy road of BLE on Android 16 First steps Check for BLE support if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { // awww snap :( No LE support }
The bumpy road of BLE on Android 17 First steps Get the Bluetooth Adapter BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = bluetoothManager.getAdapter(); (but…this also works) mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
The bumpy road of BLE on Android 18 First steps if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } Check that bluetooth is enabled
The bumpy road of BLE on Android Find me a device BluetoothAdapter. startLeScan() and LeScanCallback 19 public boolean startLeScan (BluetoothAdapter.LeScanCallback callback)
The bumpy road of BLE on Android Small bump #1 What does false mean? Most likely: Bluetooth is disabled (but you checked) Or…infamous bugs (check logcat) 20
The bumpy road of BLE on Android Find me type of device public boolean startLeScan (UUID[] serviceUuids, BluetoothAdapter.LeScanCallback callback) Does not work with 128 bit UUIDs Solution: DIY filtering stackoverflow.com/questions/18019161/startlescan-with-128-bit- uuids-doesnt-work-on-native-android-ble-implementation 24
The bumpy road of BLE on Android BluetoothLeScanner Filtering Batching of results* Power modes* ParcelUuid uuid = ParcelUuid.fromString("a495ff10-c5b1-4b44-b512-1370f02d74de"); BluetoothManager bm = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE); BluetoothAdapter adapter = bm.getAdapter(); ScanFilter scanFilter = new Builder().setServiceUuid(uuid).build(); ScanSettings settings = new ScanSettings.Builder().build(); * this asterix might spoil the party 26
The bumpy road of BLE on Android BluetoothLeScanner adapter.getBluetoothLeScanner().startScan(singletonList(scanFilter), settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { // process the result, there's currently only one callbackType defined } @Override public void onBatchScanResults(List results) { // terms and conditions apply } @Override public void onScanFailed(int errorCode) { // handle error based on the errorCode! } }); 27
The bumpy road of BLE on Android BluetoothGatt Manages the connection to the peripheral Don’t forget to close() when done, manage reference carefully! 30
The bumpy road of BLE on Android Auto connect? Advice against using autoConnect = true Behaviour is unclear Disconnect to cancel does not work on 4.3 Recommendation: manage (re)connection in your app 31
The bumpy road of BLE on Android BluetoothGattCallback Typical sequence: 1. onConnectionStateChange() 2. call discoverServices() 3. onServicesDiscovered() 4. read / write characteristics and / or subscribe to updates 5. close() when done 32
The bumpy road of BLE on Android Connection & discovery BluetoothDevice device = ... // obtained from scanning device.connectGatt(this, false, new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { if (status == BluetoothGatt.GATT_SUCCESS) { if (newState == BluetoothGatt.STATE_CONNECTED) { if (!gatt.discoverServices()) { // requesting service failed, make sure we clean up gatt.close(); } } } else { // connection failed, clean up gatt.close(); } } public void onServicesDiscovered(BluetoothGatt gatt, int status) { // find the service we like to use mSerialService = gatt.getService(BEAN_SERIAL_CHARACTERISTIC_UUID); if (mSerialService == null) { // service is not found, close the client gatt.close(); } } }); 33
The bumpy road of BLE on Android Profit! @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { // handle updated value } 37
The bumpy road of BLE on Android Notification limits There’s a hard limit on the number of notifications you can have: 4 on Android 4.3 7 on Android 4.4 15 on Android 5 38
The bumpy road of BLE on Android Writing characteristics public void write(byte[] data) { mCharacteristic.setValue(data); if (!mGatt.writeCharacteristic(mCharacteristic)) { mGatt.close(); } // important: wait for onCharacteristicWrite callback before attempting the next write! } 39
The bumpy road of BLE on Android Juggling writes By design the Bean SDK does a lot of writing Split data in 20 byte packets, write to characteristic Assemble packets from notifications Single characteristic for read/write makes it harder 40
The bumpy road of BLE on Android Conclusions Android has full support for BLE, maturing in Lollipop The BLE related API’s are is a really low level Error checking all over the place Documentation could use some work 41
The bumpy road of BLE on Android Observations Complexity managing multiple characteristics in a single callback. Low level interface seems straightforward, but is difficult to get right. Bean SDK has GattClient to solve some of those problems 42
The bumpy road of BLE on Android Learn more bitbucket.org/littlerobots/beanlib d.android.com/guide/topics/connectivity/bluetooth-le.html punchthrough.com/bean 43