Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Demystifying Android's Bluetooth Low Energy at ...

Demystifying Android's Bluetooth Low Energy at MCE^3 Conf

Presentation by Paweł Urban & Dariusz Seweryn.

Programming with a hardware in mind is fun. IoT is no longer a future but it's around us and Bluetooth programming became our reality. We'll tell you how to play with it without having a headache, using reactive concepts.

Avatar for Paweł Urban

Paweł Urban

April 22, 2016

Other Decks in Technology

Transcript

  1. DEMYSTIFYING 
 ANDROID'S 
 BLUETOOTH LOW ENERGY Paweł Urban Senior

    Software Engineer Dariusz Seweryn Senior Software Engineer
  2. Peripheral device DEVICE SENSOR 36.6°C SENSOR
 VALUE Service A Characteristic

    1 Characteristic 2 SENSOR
 CONFIGURATION READ WRITE NOTIFY
  3. Peripheral device Service A Characteristic 1 Characteristic 2 Service B

    Characteristic 3 Characteristic 4 Service C Characteristic 5 Characteristic 6 DISCOVERY
  4. BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); final boolean startLeScan = bluetoothAdapter.startLeScan(leScanCallback); BluetoothAdapter.LeScanCallback

    leScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { // processing results } }; bluetoothAdapter.stopLeScan(leScanCallback); SCAN
  5. BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); final boolean startLeScan = bluetoothAdapter.startLeScan(leScanCallback); BluetoothAdapter.LeScanCallback

    leScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { // processing results } }; bluetoothAdapter.stopLeScan(leScanCallback); SCAN
  6. BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); final boolean startLeScan = bluetoothAdapter.startLeScan(leScanCallback); BluetoothAdapter.LeScanCallback

    leScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { // processing results } }; bluetoothAdapter.stopLeScan(leScanCallback); SCAN
  7. BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); final boolean startLeScan = bluetoothAdapter.startLeScan(leScanCallback); BluetoothAdapter.LeScanCallback

    leScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { // processing results } }; bluetoothAdapter.stopLeScan(leScanCallback); SCAN
  8. BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); final boolean startLeScan = bluetoothAdapter.startLeScan( new

    UUID[]{ UUID.fromString(…) }, leScanCallback); BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { // processing results } }; bluetoothAdapter.stopLeScan(leScanCallback); SCAN
  9. BluetoothDevice remoteDevice = bluetoothAdapter.getRemoteDevice(getEnteredMacAddress()); BluetoothGatt bluetoothGatt = remoteDevice.connectGatt(context, false, callback);

    BluetoothGattCallback callback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { if (status == BluetoothGatt.GATT_SUCCESS) { if (newState == BluetoothProfile.STATE_CONNECTED) { // You are connected! } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { // Disconnected bluetoothGatt.close(); } } else { // Maybe disconnected? onDisconnectRequested(); } } }; CONNECTION
  10. BluetoothDevice remoteDevice = bluetoothAdapter.getRemoteDevice(getEnteredMacAddress()); BluetoothGatt bluetoothGatt = remoteDevice.connectGatt(context, false, callback);

    BluetoothGattCallback callback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { if (status == BluetoothGatt.GATT_SUCCESS) { if (newState == BluetoothProfile.STATE_CONNECTED) { // You are connected! } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { // Disconnected bluetoothGatt.close(); } } else { // Maybe disconnected? onDisconnectRequested(); } } }; CONNECTION
  11. BluetoothDevice remoteDevice = bluetoothAdapter.getRemoteDevice(getEnteredMacAddress()); BluetoothGatt bluetoothGatt = remoteDevice.connectGatt(context, false, callback);

    BluetoothGattCallback callback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { if (status == BluetoothGatt.GATT_SUCCESS) { if (newState == BluetoothProfile.STATE_CONNECTED) { // You are connected! } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { // Disconnected bluetoothGatt.close(); } } else { // Maybe disconnected? onDisconnectRequested(); } } }; CONNECTION
  12. BluetoothDevice remoteDevice = bluetoothAdapter.getRemoteDevice(getEnteredMacAddress()); BluetoothGatt bluetoothGatt = remoteDevice.connectGatt(context, false, callback);

    BluetoothGattCallback callback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { if (status == BluetoothGatt.GATT_SUCCESS) { if (newState == BluetoothProfile.STATE_CONNECTED) { // You are connected! } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { // Disconnected bluetoothGatt.close(); } } else { // Maybe disconnected? onDisconnectRequested(); } } }; CONNECTION
  13. BluetoothDevice remoteDevice = bluetoothAdapter.getRemoteDevice(getEnteredMacAddress()); BluetoothGatt bluetoothGatt = remoteDevice.connectGatt(context, false, callback);

    BluetoothGattCallback callback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { if (status == BluetoothGatt.GATT_SUCCESS) { if (newState == BluetoothProfile.STATE_CONNECTED) { // You are connected! } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { // Disconnected bluetoothGatt.close(); } } else { // Maybe disconnected? onDisconnectRequested(); } } }; CONNECTION
  14. boolean startedDiscovering = bluetoothGatt.discoverServices(); @Override public void onServicesDiscovered(BluetoothGatt gatt, int

    status) { if (status == BluetoothGatt.GATT_SUCCESS) { BluetoothGattService service = gatt.getService(serviceUUID); BluetoothGattCharacteristic characteristic = service.getCharacteristic(characteristicUUID); boolean startedReadOperation = gatt.readCharacteristic(characteristic); // ... } else { // ... } } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { byte[] characteristicValue = characteristic.getValue(); } else { // ... } } READING DATA
  15. boolean startedDiscovering = bluetoothGatt.discoverServices(); @Override public void onServicesDiscovered(BluetoothGatt gatt, int

    status) { if (status == BluetoothGatt.GATT_SUCCESS) { BluetoothGattService service = gatt.getService(serviceUUID); BluetoothGattCharacteristic characteristic = service.getCharacteristic(characteristicUUID); boolean startedReadOperation = gatt.readCharacteristic(characteristic); // ... } else { // ... } } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { byte[] characteristicValue = characteristic.getValue(); } else { // ... } } READING DATA
  16. boolean startedDiscovering = bluetoothGatt.discoverServices(); @Override public void onServicesDiscovered(BluetoothGatt gatt, int

    status) { if (status == BluetoothGatt.GATT_SUCCESS) { BluetoothGattService service = gatt.getService(serviceUUID); BluetoothGattCharacteristic characteristic = service.getCharacteristic(characteristicUUID); boolean startedReadOperation = gatt.readCharacteristic(characteristic); // ... } else { // ... } } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { byte[] characteristicValue = characteristic.getValue(); } else { // ... } } READING DATA
  17. boolean startedDiscovering = bluetoothGatt.discoverServices(); @Override public void onServicesDiscovered(BluetoothGatt gatt, int

    status) { if (status == BluetoothGatt.GATT_SUCCESS) { BluetoothGattService service = gatt.getService(serviceUUID); BluetoothGattCharacteristic characteristic = service.getCharacteristic(characteristicUUID); boolean startedReadOperation = gatt.readCharacteristic(characteristic); // ... } else { // ... } } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { byte[] characteristicValue = characteristic.getValue(); } else { // ... } } READING DATA
  18. @Override void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) @Override void onCharacteristicRead(BluetoothGatt gatt,

    BluetoothGattCharacteristic characteristic, int status) @Override void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) @Override void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) @Override void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) @Override void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) @Override void onServicesDiscovered(BluetoothGatt gatt, int status) @Override void onMtuChanged(BluetoothGatt gatt, int mtu, int status) @Override void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) @Override void onReliableWriteCompleted(BluetoothGatt gatt, int status)
  19. Declaration of what we want to achieve Device Scanning Connecting

    to device Reading Characteristic Value Read Characteristic Establish Connection