Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

MCE^3 - Dariusz Seweryn, Paweł Urban - Demystifying Android's Bluetooth Low Energy

157 views

Published on

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.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

MCE^3 - Dariusz Seweryn, Paweł Urban - Demystifying Android's Bluetooth Low Energy

  1. 1. DEMYSTIFYING 
 ANDROID'S 
 BLUETOOTH LOW ENERGY Paweł Urban Senior Software Engineer Dariusz Seweryn Senior Software Engineer
  2. 2. BLUETOOTH LOW ENERGY
  3. 3. BLUETOOTH LOW ENERGY ANDROID’S NATIVE SUPPORT
  4. 4. BLUETOOTH LOW ENERGY ANDROID’S NATIVE SUPPORT YOUR SECRET WEAPON
  5. 5. WHY SHOULD I CARE 
 ABOUT BLE?
  6. 6. The Internet of Things – infographicThe Connectivist based on Cisco data
  7. 7. 2006
  8. 8. 2006 2010
  9. 9. 2006 2010 2013
  10. 10. A DEVELOPER
 PERSPECTIVE
  11. 11. Jelly Bean
  12. 12. BACKWARD SUPPORT
  13. 13. BACKWARD SUPPORT
  14. 14. BACKWARD SUPPORT BETA
  15. 15. BACKWARD SUPPORT BETA
  16. 16. LOW ENERGY
  17. 17. GAP (GENERIC ACCESS PROFILE)
  18. 18. PERIPHERAL
  19. 19. PERIPHERAL CENTRAL
  20. 20. PERIPHERAL CENTRAL ADVERTISE PRESENCE
  21. 21. PERIPHERAL CENTRAL ADVERTISE PRESENCE CONNECTION HANDSHAKE
  22. 22. CLIENT PERIPHERAL CENTRAL ADVERTISE PRESENCE CONNECTION HANDSHAKE SERVER
  23. 23. CLIENT PERIPHERAL CENTRAL ADVERTISE PRESENCE CONNECTION HANDSHAKE SERVER READ/WRITE DATA REQ RESPOND WITH DATA
  24. 24. GATT (Generic Attribute Profile)
  25. 25. Texas Instruments
 SensorTAG
  26. 26. Peripheral device Service A Characteristic 1 Characteristic 2 DEVICE
  27. 27. Peripheral device DEVICE SENSOR Service A Characteristic 1 Characteristic 2
  28. 28. Peripheral device DEVICE SENSOR 36.6°C SENSOR
 VALUE Service A Characteristic 1 Characteristic 2
  29. 29. Peripheral device DEVICE SENSOR 36.6°C SENSOR
 VALUE Service A Characteristic 1 Characteristic 2 SENSOR
 CONFIGURATION
  30. 30. Peripheral device DEVICE SENSOR 36.6°C SENSOR
 VALUE Service A Characteristic 1 Characteristic 2 SENSOR
 CONFIGURATION READ WRITE NOTIFY
  31. 31. Peripheral device Service A Characteristic 1 Characteristic 2 Service B Characteristic 3 Characteristic 4 Service C Characteristic 5 Characteristic 6 DISCOVERY
  32. 32. UUID 1 TEMPERATURE(„4E99FFF1-4B3E-11E5-9D65-0002A5D5C51B"); 2 HUMIDITY(„4E99FFF2-4B3E-11E5-9D65-0002A5D5C51B"); 3 TIME(„5E99FFC1-4B3E-11E5-9D65-0002A5D5C51B"); 4 DEVICE_NAME(„00002a26-0000-1000-8000-00805f9b34fb”);
  33. 33. UUID 1 TEMPERATURE(„4E99FFF1-4B3E-11E5-9D65-0002A5D5C51B"); 2 HUMIDITY(„4E99FFF2-4B3E-11E5-9D65-0002A5D5C51B"); 3 TIME(„5E99FFC1-4B3E-11E5-9D65-0002A5D5C51B"); 4 DEVICE_NAME(„00002a26-0000-1000-8000-00805f9b34fb”); 128-bit
  34. 34. UUID 1 TEMPERATURE(„4E99FFF1-4B3E-11E5-9D65-0002A5D5C51B"); 2 HUMIDITY(„4E99FFF2-4B3E-11E5-9D65-0002A5D5C51B"); 3 TIME(„5E99FFC1-4B3E-11E5-9D65-0002A5D5C51B"); 4 DEVICE_NAME(„00002a26-0000-1000-8000-00805f9b34fb”); 16-bit
  35. 35. THE SCARY PART
  36. 36. 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
  37. 37. 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
  38. 38. 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
  39. 39. 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
  40. 40. 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
  41. 41. 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
  42. 42. 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
  43. 43. 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
  44. 44. 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
  45. 45. 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
  46. 46. 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
  47. 47. 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
  48. 48. 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
  49. 49. 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
  50. 50. @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)
  51. 51. DOES IT HAVETO BE HARD?
  52. 52. RxAndroidBLE No! Just use
  53. 53. RXJAVA
  54. 54. OBSERVABLE RXJAVA
  55. 55. Device Scanning OBSERVABLE
  56. 56. Device Scanning Scanned device
  57. 57. Device Scanning Scanned device
  58. 58. Device Scanning Scanned device
  59. 59. Device Scanning
  60. 60. Device Scanning Establish Connection
  61. 61. Device Scanning Connecting to device Establish Connection
  62. 62. Device Scanning Connecting to device Establish Connection
  63. 63. Read Characteristic Device Scanning Connecting to device Establish Connection
  64. 64. Device Scanning Connecting to device Reading CharacteristicValue Read Characteristic Establish Connection
  65. 65. Device Scanning Connecting to device Reading CharacteristicValue Read Characteristic Establish Connection
  66. 66. Declaration of what we want to achieve Device Scanning Connecting to device Reading CharacteristicValue Read Characteristic Establish Connection
  67. 67. Device Scanning Connecting to device Reading CharacteristicValue Read Characteristic Establish Connection
  68. 68. Device Scanning Connecting to device Some action Do something Establish Connection
  69. 69. Device Scanning Connecting to device Some action Do something Establish Connection
  70. 70. Device Scanning Connecting to device Some action Do something Establish Connection
  71. 71. THE DEMO
  72. 72. SAYTHAT AGAIN?
  73. 73. Q&As?
  74. 74. LET’S CHAT! @DSeweryn +PawełUrban https://git.io/vw8PM
  75. 75. ThankYou! @DSeweryn +PawełUrban https://git.io/vw8PM

×