Date post: | 14-Feb-2017 |
Category: |
Devices & Hardware |
Upload: | pawel-urban |
View: | 91 times |
Download: | 1 times |
DEMYSTIFYING ANDROID'S BLUETOOTH LOW ENERGY
Paweł UrbanSenior Software Engineer
Dariusz SewerynSenior Software Engineer
BLUETOOTH LOW ENERGY
BLUETOOTH LOW ENERGY
ANDROID’S NATIVE SUPPORT
BLUETOOTH LOW ENERGY
ANDROID’S NATIVE SUPPORT
YOUR SECRET WEAPON
WHY SHOULD I CARE ABOUT BLE?
The Internet of Things – infographic The Connectivist based on Cisco data
2006
2006 2010
2006 2010 2013
A DEVELOPER PERSPECTIVE
Jelly Bean
BACKWARD SUPPORT
BACKWARD SUPPORT
BACKWARD SUPPORTBETA
BACKWARD SUPPORTBETA
LOW ENERGY
GAP (GENERIC ACCESS PROFILE)
PERIPHERAL
PERIPHERAL CENTRAL
PERIPHERAL CENTRAL
ADVERTISE PRESENCE
PERIPHERAL CENTRAL
ADVERTISE PRESENCECONNECTION HANDSHAKE
CLIENT
PERIPHERAL CENTRAL
ADVERTISE PRESENCECONNECTION HANDSHAKE
SERVER
CLIENT
PERIPHERAL CENTRAL
ADVERTISE PRESENCECONNECTION HANDSHAKE
SERVER
READ/WRITE DATA REQ
RESPOND WITH DATA
GATT (Generic Attribute Profile)
Texas Instruments SensorTAG
Peripheral device
Service A
Characteristic 1 Characteristic 2
DEVICE
Peripheral deviceDEVICE
SENSOR
Service A
Characteristic 1 Characteristic 2
Peripheral deviceDEVICE
SENSOR
36.6°C SENSOR VALUE
Service A
Characteristic 1 Characteristic 2
Peripheral deviceDEVICE
SENSOR
36.6°C SENSOR VALUE
Service A
Characteristic 1 Characteristic 2
SENSOR CONFIGURATION
Peripheral deviceDEVICE
SENSOR
36.6°C SENSOR VALUE
Service A
Characteristic 1 Characteristic 2
SENSOR CONFIGURATION
READ WRITE NOTIFY
Peripheral device
Service A
Characteristic 1 Characteristic 2
Service B
Characteristic 3 Characteristic 4
Service C
Characteristic 5 Characteristic 6
DISCOVERY
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”);
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
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
THE SCARY PART
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
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
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
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
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
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
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
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
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
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
boolean startedDiscovering = bluetoothGatt.discoverServices();
@Overridepublic 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 { // ... }}
@Overridepublic void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { byte[] characteristicValue = characteristic.getValue(); } else { // ... }}
READING DATA
boolean startedDiscovering = bluetoothGatt.discoverServices();
@Overridepublic 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 { // ... }}
@Overridepublic void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { byte[] characteristicValue = characteristic.getValue(); } else { // ... }}
READING DATA
boolean startedDiscovering = bluetoothGatt.discoverServices();
@Overridepublic 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 { // ... }}
@Overridepublic void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { byte[] characteristicValue = characteristic.getValue(); } else { // ... }}
READING DATA
boolean startedDiscovering = bluetoothGatt.discoverServices();
@Overridepublic 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 { // ... }}
@Overridepublic void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { byte[] characteristicValue = characteristic.getValue(); } else { // ... }}
READING DATA
@Override void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)@Overridevoid onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)@Overridevoid onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)@Overridevoid onConnectionStateChange(BluetoothGatt gatt, int status, int newState)@Overridevoid onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status)@Overridevoid onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status)@Overridevoid onServicesDiscovered(BluetoothGatt gatt, int status)@Overridevoid onMtuChanged(BluetoothGatt gatt, int mtu, int status)@Overridevoid onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status)@Overridevoid onReliableWriteCompleted(BluetoothGatt gatt, int status)
DOES IT HAVE TO BE HARD?
RxAndroidBLENo! Just use
RXJAVA
OBSERVABLE
RXJAVA
Device Scanning
OBSERVABLE
Device Scanning
Scanned device
Device Scanning
Scanned device
Device Scanning
Scanned device
Device Scanning
Device Scanning
Establish Connection
Device Scanning
Connecting to deviceEstablish Connection
Device Scanning
Connecting to deviceEstablish Connection
Read Characteristic
Device Scanning
Connecting to deviceEstablish Connection
Device Scanning
Connecting to device
Reading Characteristic ValueRead Characteristic
Establish Connection
Device Scanning
Connecting to device
Reading Characteristic ValueRead Characteristic
Establish Connection
Declaration of what we want to achieve
Device Scanning
Connecting to device
Reading Characteristic ValueRead Characteristic
Establish Connection
Device Scanning
Connecting to device
Reading Characteristic ValueRead Characteristic
Establish Connection
Device Scanning
Connecting to device
Some action
Do something
Establish Connection
Device Scanning
Connecting to device
Some action
Do something
Establish Connection
Device Scanning
Connecting to device
Some action
Do something
Establish Connection
THE DEMO
SAY THAT AGAIN?
Q&As?
LET’S CHAT!
@DSeweryn
+PawełUrban
https://git.io/vw8PM
Thank You!@DSeweryn +PawełUrban
https://git.io/vw8PM