32 bits le!, top 16 are always 0 0x180D (Heart Rate Service) is the same as 0000180D-0000-1000-8000-00805F9B34FB Practical Bluetooth Low Energy on Android - @ErikHellman / www.hellso!.se
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .build(); // Name or address of peripherla is known ScanFilter.Builder builder = new ScanFilter.Builder(); builder.setDeviceAddress(deviceAddress); // MAC address builder.setDeviceName(deviceName); // Name of device builder.setServiceUuid(SERVICE_UUID); builder.setServiceData(SERVICE_UUID, serviceData); ScanFilter scanFilter = builder.build(); bluetoothLeScanner.startScan(Collections.singletonList(scanFilter), scanSettings, callback); Practical Bluetooth Low Energy on Android - @ErikHellman / www.hellso!.se
assume the device is nearby: public void connectToDevice(BluetoothAdapter adapter, String address, MyGattCallback gattCallback) { BluetoothDevice device = adapter.getRemoteDevice(address); // TODO Set a timeout somewhere... device.connectGatt(context, true, gattCallback); } Practical Bluetooth Low Energy on Android - @ErikHellman / www.hellso!.se
// Learn what auto-connect parameter means! device.connectGatt(context, true, gattCallback); } Practical Bluetooth Low Energy on Android - @ErikHellman / www.hellso!.se
happen on a Binder thread! Never block the BluetoothGattCallback methods! Use a HandlerThread for all GATT operations! Practical Bluetooth Low Energy on Android - @ErikHellman / www.hellso!.se
implements Handler.Callback { public static final int MSG_CONNECT = 10; public static final int MSG_DISCOVER_SERVICES = 20; private Handler bleHandler; private Context context; public MyGattCallback(Context context) { this.context = context; HandlerThread handlerThread = new HandlerThread("BLE-Worker"); handlerThread.start(); bleHandler = new Handler(handlerThread.getLooper(), this); } public void connect(String address) { bleHandler.obtainMessage(MSG_CONNECT, address) .sendToTarget(); } public void dispose() { // TODO Probably disconnect as well? bleHandler.removeCallbacksAndMessages(null); bleHandler.getLooper().quit(); } Practical Bluetooth Low Energy on Android - @ErikHellman / www.hellso!.se
c) { gatt.setCharacteristicNotification(c, true); // This is usually needed as well... BluetoothGattDescriptor desc = c.getDescriptor(INPUT_DESC_ID); desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); gatt.writeDescriptor(desc); } Practical Bluetooth Low Energy on Android - @ErikHellman / www.hellso!.se
BluetoothGattCharacteristic c) { super.onCharacteristicChanged(gatt, c); if(INPUT_CHAR_UUID.equals(c.getUuid()) { // Extract value in callback and pass to worker thread! byte[] value = c.getValue(); bleHandler.obtainMessage(MSG_NOTIFY_DATA_CHANGED, value) .sendToTarget(); } } Practical Bluetooth Low Energy on Android - @ErikHellman / www.hellso!.se
of a write operation is 20 bytes! (except for devices supporting BluetoothGatt.requestMtu()) Practical Bluetooth Low Energy on Android - @ErikHellman / www.hellso!.se
Status status; public final GattPeripheral peripheral; public GattEvent(GattPeripheral peripheral, Status status) { this.peripheral = peripheral; this.status = status; } public enum Status { Success, Failed } } Practical Bluetooth Low Energy on Android - @ErikHellman / www.hellso!.se
enum State { Connected, Disconnected, Connecting, Disconnecting; } public final State newState; public ConnectionChangedEvent(GattPeripheral peripheral, Status status, State newState) { super(peripheral, status); this.newState = newState; } } Practical Bluetooth Low Energy on Android - @ErikHellman / www.hellso!.se
Log all BluetoothGattCallback calls and their data · Enable Bluetooth HCI snoop log Practical Bluetooth Low Energy on Android - @ErikHellman / www.hellso!.se