$30 off During Our Annual Pro Sale. View Details »

Everything About Bluetooth (淺談藍牙 4.0) - Central 篇

Everything About Bluetooth (淺談藍牙 4.0) - Central 篇

講解 Bluetooth 的 GATT 的概念,並以 Android 實作
Example code:
Peripheral - BLE CPU Temp
https://github.com/j796160836/Ble-CPUTemp-Android
Central - BLE Temperature Receiver
https://github.com/j796160836/BleTemperatureReceiver-Android

Johnny Sung

October 22, 2015
Tweet

More Decks by Johnny Sung

Other Decks in Programming

Transcript

  1. • Heart Rate Service • Heart Rate Measurement • Data

    • Descriptor 00002A37-0000-1000-8000-00805F9B34FB GATT Heart Rate Monitor 0000180D-0000-1000-8000-00805F9B34FB Property: Notify
  2. Property: Indicate • Health Thermometer • Temperature Measurement • Data

    • Descriptor GATT Health Thermometer 00001809-0000-1000-8000-00805F9B34FB 00002A1C-0000-1000-8000-00805F9B34FB
  3. • an indicate operation is identical to a notify operation

    except that indications are acknowledged, while notifications are not. Notify vs Indicate http://mbientlab.com/blog/bluetooth-low-energy-introduction/
  4. Property: Indicate • Health Thermometer • Temperature Measurement • Data

    • Descriptor GATT Health Thermometer 00001809-0000-1000-8000-00805F9B34FB 00002A1C-0000-1000-8000-00805F9B34FB
  5. • Central • Android 4.3 (API Level 18) • Peripheral

    • Android 5.0 (API Level 21) • Specific BLE chip Requirement in Android
  6. • Discover • Connect • Explore • Interact Central֥ඹἠᾲ؍ 

    䵃㼦酤縨  鸮䱺  䱳程须俲穡圓  ✽⹛
  7. Bluetooth⃴ཋ ⃷ק൞ڎᆦჱ#-& getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE) @Override
 public void onActivityResult(int requestCode , int

    resultCode, Intent data) {
 if (requestCode == REQUEST_ENABLE_BT) {
 if (resultCode == Activity.RESULT_OK) {
 // Bluetooth has turned on
 } else {
 // User did not enable Bluetooth or an error occurred
 }
 }
 } Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
 startActivityForResult(enableIntent, REQUEST_ENABLE_BT); ေ౰յῘῴ࿩
  8. Discover ෆ⇨⊬ᇂ BluetoothManager manager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
 BluetoothAdapter adapter =

    manager.getAdapter(); adapter.startLeScan(scanCallback); adapter.stopLeScan(scanCallback); ଦ֞#MVFUPPUI"EBQUFS Ῐ൓ෆ⇨ ᾵ඏෆ⇨ This method was deprecated in API level 21 API level 18
  9. Discover ෆ⇨⊬ᇂ BluetoothAdapter.LeScanCallback scanCallback =
 new BluetoothAdapter.LeScanCallback() {
 @Override
 public

    void onLeScan(final BluetoothDevice device , final int rssi , byte[] scanRecord) {
 addDevice(device, rssi);
 // Add device to list
 }
 }; ෆ⇨֥$BMMCBDL This method was deprecated in API level 21 API level 18
  10. scanner.stopScan(scanCallback); scanner.startScan(filters, settings, scanCallback); Ῐ൓ෆ⇨ ᾵ඏෆ⇨ Discover ෆ⇨⊬ᇂ ڿႨ#MVFUPPUI-F4DBOOFS API

    level 21 BluetoothManager manager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
 BluetoothAdapter adapter = manager.getAdapter(); BluetoothLeScanner scanner = adapter.getBluetoothLeScanner(); // Setting ScanFilter and ScanSettings
  11. Discover ෆ⇨⊬ᇂ ArrayList<ScanFilter> filters = new ArrayList<>();
 ScanFilter.Builder fb =

    new ScanFilter.Builder();
 fb.setServiceUuid(new ParcelUuid(UUID.fromString("...")));
 filters.add(fb.build()); 
 ScanSettings.Builder sb = new ScanSettings.Builder();
 ScanSettings settings = sb.build(); ෆ⇨⇢⇊ API level 21
  12. Discover ෆ⇨⊬ᇂ ෆ⇨⇢⇊ • ScanFilter • ServiceUuid • ServiceData •

    DeviceAddress • DeviceName • ManufacturerData API level 21
  13. Discover ෆ⇨⊬ᇂ ෆ⇨⇢⇊ • ScanSettings • CallbackType (All matches /

    First match / Match lost) • MatchMode • NumOfMatches • ScanMode (Low latency / Balanced / Low power) API level 21
  14. ScanCallback scanCallback = new ScanCallback() {
 @Override
 public void onScanResult(int

    callbackType , ScanResult result) {
 if (callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES) {
 // Add device to list
 }
 }
 
 @Override
 public void onScanFailed(int errorCode) {
 Log.e("Scan Failed", "Error Code: " + errorCode);
 } @Override
 public void onBatchScanResults(List<ScanResult> results) { }
 }; Discover ෆ⇨⊬ᇂ ෆ⇨$BMMCBDL API level 21
  15. Connect ’ࢤ⊬ᇂ ’ࢤ⊬ᇂ String deviceAddress = "0A:0B:0C:0D:0F:10";
 BluetoothDevice device =

    BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address); BluetoothGatt mBluetoothGatt = device.connectGatt(this, false, mGattCallback); API level 18
  16. private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
 @Override
 public

    void onConnectionStateChange(BluetoothGatt gatt , int status, int newState) {
 switch (newState) {
 case BluetoothProfile.STATE_CONNECTED: // do discoverServices
 break;
 case BluetoothProfile.STATE_DISCONNECTED:
 break;
 
 case BluetoothProfile.STATE_CONNECTING:
 case BluetoothProfile.STATE_DISCONNECTING:
 break;
 }
 }
 
 // More ...
 }; Connect ’ࢤ⊬ᇂ (BUU$BMMCBDL API level 18
  17. Explore ฐ෬⊷ਘ᾵ἧ ෆ⇨4FSWJDFT API level 18 mBluetoothGatt.discoverServices(); private final BluetoothGattCallback

    mGattCallback = new BluetoothGattCallback() {
 // ... Continued 
 @Override
 public void onServicesDiscovered(BluetoothGatt gatt , int status) {
 if (status == BluetoothGatt.GATT_SUCCESS) {
 // Do Something
 }
 } // More ...
 }; (BUU$BMMCBDL ⇟
  18. Explore ฐ෬⊷ਘ᾵ἧ ౼֤4FSWJDFT API level 18 BluetoothGattService gattService = mBluetoothGatt.getService(UUID.fromString("..."));


    BluetoothGattCharacteristic characteristic = gattService.getCharacteristic(UUID.fromString("..."));
 ౼֤$IBSBDUFSJTUJD
  19. Interact ޺ọ ồ౼$IBSBDUFSJTUJD֥ᆴ API level 18 byte[] bytes = characteristic.getValue();

    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { // ... Continued
 @Override
 public void onCharacteristicRead(BluetoothGatt gatt,
 BluetoothGattCharacteristic characteristic, int status) {
 if (status == BluetoothGatt.GATT_SUCCESS) {
 // Do Something
 }
 } // More ...
 }; (BUU$BMMCBDL ⇟
  20. Interact ޺ọ ồ౼$IBSBDUFSJTUJD֥ᆴ API level 18 byte[] bytes = characteristic.getValue();

    float floatValue = characteristic.getFloatValue( BluetoothGattCharacteristic.FORMAT_FLOAT, 0); 
 int intValue = characteristic.getIntValue( BluetoothGattCharacteristic.FORMAT_SINT8, 0); 
 int uintValue = characteristic.getIntValue( BluetoothGattCharacteristic.FORMAT_UINT8, 0); 
 String stringValue = characteristic.getStringValue(0); ὕॖၛ≾∄ồ౼ mBluetoothGatt.setCharacteristicNotification(characteristic, true);
 UUID CCCD = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
 BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CCCD);
 descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
 mBluetoothGatt.writeDescriptor(descriptor);
  21. Interact ޺ọ 䩏⤳$IBSBDUFSJTUJD֥/PUGJDBUJPO۷ྍ API level 18 mBluetoothGatt.setCharacteristicNotification(characteristic, true);
 UUID CCCD

    = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
 BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CCCD);
 descriptor.setValue( BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
 mBluetoothGatt.writeDescriptor(descriptor); private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { // ... Continued
 @Override
 public void onCharacteristicChanged(BluetoothGatt gatt,
 BluetoothGattCharacteristic characteristic) {
 // Do Something
 }
 }; (BUU$BMMCBDL ⇟
  22. Develop tools https://play.google.com/store/apps/details?id=no.nordicsemi.android.nrftoolbox nRF Toolbox https://itunes.apple.com/tw/app/id557428110 LightBlue Explorer (iOS) https://itunes.apple.com/us/app/id820906058

    nRF Toolbox (iOS) https://play.google.com/store/apps/details?id=com.kyriakosalexandrou.bluetoothsupportcheck BLE Central,Peripheral Check https://play.google.com/store/apps/details?id=com.macdom.ble.blescanner BLE Scanner: Read,Write,Notify Andorid
  23. MessageHorn for Android Wear When messaging Connected to device Device

    selection Main https://play.google.com/store/apps/details?id=com.JohnnyWorks.messagehorn
  24. Q&A