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

つらくない(?) Bluetooth Low Energy on Android / TSURAI BLE on Android

Masayuki Izumi
September 07, 2015

つらくない(?) Bluetooth Low Energy on Android / TSURAI BLE on Android

Masayuki Izumi

September 07, 2015
Tweet

More Decks by Masayuki Izumi

Other Decks in Technology

Transcript

  1.  Rekimoto Lab. at the University of Tokyo (2008-2015: Akashi-NCT)

     Enginner at Wantedly, Inc. (2014.9-2015.2: Dmetlabel, Inc.)
  2. Android 4.3 (API Level 18) introduces built-in platform support for

    Bluetooth Low Energy in the central role and provides APIs that apps can use to discover devices, query for services, and read/write characteristics. - Bluetooth Low Energy | Android Developers
  3. BluetoothGatt Bluetooth LE の周辺機器は、サーバとして、センサの値、動作設定 値、内部状態などを公開しています。Bluetooth LE は、ある機能を サービスという単位にまとめます。1 つのサービスは複数のキャラ クタリスティクスを持ちます。例えばエアコンであれば、室内温度

    というサービスを作り、そのなかに気温センサの値というキャラク タリスティクスをもたせる設計をしたりします。 - BLE の通信仕様 - Reinforce-Lab.'s Blog* * http://reinforce-lab.github.io/blog/2013/08/13/blebook-ch2-ble-spec/
  4. BluetootGatt  GATT (Generic Attribute Profile)  あらゆる BLE 端末は

    GATT に基いて データの送受信を行う  Android では BluetoothGatt クラスを利用する
  5. BluetootGatt  GATT (Generic Attribute Profile)  あらゆる BLE 端末は

    GATT に基いて データの送受信を行う  Android では BluetoothGatt クラスを利用する ↑ こいつが闇
  6. BLE つらい問題 ちょっと触ってみた結果、どうにも悲しいことに 「1. 安定性がイケてない」 「2. SDK サンプルがイケてない」 「3. API

    仕様がイケてない」 という三重苦です。 - Android の BLE で Characteristics の Read/Write サンプルを作ってみた - ReDo** ** http://greety.sakura.ne.jp/redo/2013/11/androidblecharacteristicsreadwrite.html
  7. BLE つらい問題 ちょっと触ってみた結果、どうにも悲しいことに 「1. 安定性がイケてない」 「2. SDK サンプルがイケてない」 「3. API

    仕様がイケてない」 という三重苦です。 - Android の BLE で Characteristics の Read/Write サンプルを作ってみた - ReDo** ** http://greety.sakura.ne.jp/redo/2013/11/androidblecharacteristicsreadwrite.html
  8. BluetoothGattCallback onConnectionStateChange(BluetoothGatt gatt, int status, int newState) onServicesDiscovered(BluetoothGatt gatt, int

    status) onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)
  9. BluetoothGattCallback onConnectionStateChange(BluetoothGatt gatt, int status, int newState) onServicesDiscovered(BluetoothGatt gatt, int

    status) onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)
  10. BluetoothGattCallback  接続処理 BluetoothDevice#connectGatt() → onConnectionStateChange()  Service 探し BluetoothGatt#discoverService()

    → onServiceDiscovered()  書き込み BluetoothGatt#writeCharacteristic() → onCharacteristicWrite()
  11. BluetoothGattCallback  接続処理 BluetoothDevice#connectGatt() → onConnectionStateChange()  Service 探し BluetoothGatt#discoverService()

    → onServiceDiscovered()  書き込み BluetoothGatt#writeCharacteristic() → onCharacteristicWrite()  切断処理 BluetoothGatt#disconnect() → onConnectionStateChange()
  12. BluetoothGattCallback  接続処理 BluetoothDevice#connectGatt() → onConnectionStateChange()  Service 探し BluetoothGatt#discoverService()

    → onServiceDiscovered()  書き込み BluetoothGatt#writeCharacteristic() → onCharacteristicWrite()  切断処理 BluetoothGatt#disconnect() → onConnectionStateChange()
  13. BluetoothGattCallback  接続処理 BluetoothDevice#connectGatt() → onConnectionStateChange()  Service 探し BluetoothGatt#discoverService()

    → onServiceDiscovered()  書き込み BluetoothGatt#writeCharacteristic() → onCharacteristicWrite()  切断処理 BluetoothGatt#disconnect() → onConnectionStateChange() ↓ 切断は disconnect() して, callback を待ってから close()
  14. 対策①: 状態を意識する private static final int STATE_DISCONNECTED = 0; private

    static final int STATE_CONNECTING = 1; private static final int STATE_CONNECTED = 2; 公式サンプル
  15. 対策①: 状態を意識する private static final int STATE_DISCONNECTED = 0; private

    static final int STATE_CONNECTING = 1; private static final int STATE_CONNECTED = 2; 公式サンプル たりない
  16. 対策②: e.g. Enum でハンドリング @Override public onCharacteristicWrite() { CharacteristicHandler.valueOf(characteristic.getUuid()) .handle(characteristic);

    } enum CharacteristicHandler { DIGITAL_WRITE(/* ... */), DIGITAL_READ(/* ... */) UNKNOWN(null); public static CharacteristicHandler valueOf(UUID uuid) { /* ... */ } public UUID getUUID() { /* ... */ } public void handle() { /* ... */ } }
  17. 対策②: e.g. Enum でハンドリング @Override public onCharacteristicWrite() { CharacteristicHandler.valueOf(characteristic.getUuid()) .handle(characteristic);

    } enum CharacteristicHandler { DIGITAL_WRITE(/* ... */), DIGITAL_READ(/* ... */) UNKNOWN(null); public static CharacteristicHandler valueOf(UUID uuid) { /* ... */ } public UUID getUUID() { /* ... */ } public void handle() { /* ... */ } }
  18. 対策②: e.g. Enum でハンドリング @Override public onCharacteristicWrite(/* ... */) {

    CharacteristicHandler.valueOf(characteristic.getUuid()) .handle(characteristic); } enum CharacteristicHandler { DIGITAL_WRITE(/* ... */), DIGITAL_READ(/* ... */) UNKNOWN(null); public static CharacteristicHandler valueOf(UUID uuid) { /* ... */ } public UUID getUUID() { /* ... */ } public void handle() { /* ... */ } }
  19. 対策②: e.g. Enum でハンドリング @Override public onCharacteristicWrite(/* ... */) {

    CharacteristicHandler.valueOf(characteristic.getUuid()) .handle(characteristic); } enum CharacteristicHandler { DIGITAL_WRITE(/* ... */), DIGITAL_READ(/* ... */) UNKNOWN(null); public static CharacteristicHandler valueOf(UUID uuid) { /* ... */ } public UUID getUUID() { /* ... */ } public void handle() { /* ... */ } }
  20. 対策②: Callback のハンドリング  どの操作のコールバックかを判断するには, 引数に入ってるインスタンス見るしかない  普通にやると Callback Hell

    不可避  上手く処理を移譲させないとヤバい (数千行のなんちゃら Manager クラスとかと対峙するはめに…)
  21.  イイ感じのパターンでラップしちゃうのもある e.g. Rx, Promise, Observer, flux  出回ってる BLE

    デバイスの SDK はつらい (ハッカソンとかではそのことを念頭に置いた方がいい) 余談
  22.  イイ感じのパターンでラップしちゃうのもある e.g. Rx, Promise, Observer, flux  出回ってる BLE

    デバイスの SDK はつらい (ハッカソンとかではそのことを念頭に置いた方がいい)  BLE まわり,ユニットテストどうするの? (BluetoothGatt は final なので… ラッパー書くしかない?) 余談