Bletia: AndroidのBLE周りをモダンなAPIで扱う

## TL;DR

* [**Bletia**][bletia]を利用すればモダンな感じにBLEで遊べるよ！
  - なんかSDK作ったりするのも楽ちんだよ！ 
  - **RxBletia**を利用すればRxJavaなAPIでBLE扱えるよ！

## AndroidのBLEつらい問題
これについては先人たちが散々語ってくれているのと，僕自身もkyobashi.dexやpotatotips，情報科学若手の会といった勉強会で紹介したことがあるような気がするので割愛する．

* [AndroidのBLEでCharacteristicsのRead/Writeサンプルを作ってみた - ReDo][youten]
* [kyobashi.dexでAndroidのBLEがつらい話してきた #kyobashidex - うさみみを生やせ] [kyobashi-dex]
* [#potatotips でBLEのつらさを軽減する話してきた - うさみみを生やせ][potatotips]
* [こわくないBLE / BLE is afraid // Speaker Deck][wakate]

とりあえずつらい．
potatotipsと情報科学若手の会で紹介したBLEのつらさ解消ライブラリ「[Bletia][bletia]」がv2.0にあがったので改めて紹介する．

## Bletia / RxBletia
[**Bletia**][bletia]BLEまわりのAPIを[JDeferred][jdeferred]の`Promise`でラップしてくれるライブラリである．また，Bletia v1.xは[konashi SDK for Android][konashi-sdk]のバックエンドでも利用されている．

### 何が出来るか
* `readCharacteristic()`や`writeDescriptor()`などのGattへの操作をいい感じにキューイングしてくれる
* Callback-baseなAPIを比較的モダンなPromiseやRxでラップしてくれる
* エラー時は[マジックナンバーエラーコードではなくExceptionを返してくれる ](https://github.com/izumin5210/Bletia/blob/master/bletia-core/src/main/java/info/izumin/android/bletia/core/BluetoothGattCallbackHandler.java)
* 各種APIは~Actionという形を取り，これらを継承することで独自のAPIを生やすことが出来る
  - 例えば[konashi SDK for Android][konashi-sdk]では`PioPinModeAction`や`PioDigitalWriteAction`などのクラスを用意し，内部では`Bletia#execute()`にそれらActionのインスタンスを喰わせることでkonashi専用APIを実装している
  - `Action`クラスの実装によってはcharacteristicやdescriptorに喰わせる値のvalidation等も仕込むことが出来る
  - fluxから着想を得た…が，跡形も無い :innocent:

もとは世に蔓延るBLEデバイスのAndroid向けSDKのバックエンドのつらい部分を全て背負うために生まれたライブラリなので，`WriteCharacteristicAction`や`ReadCharacteristicAction`を拡張したクラスを実装することでいい感じに手を抜きつつ，しかもtestableな感じでSDKを作ることが出来るように設計されている．

### 名前の由来
[Bletia](https://en.wikipedia.org/wiki/Bletia)はラン科の花らしい．[こんな感じ](https://www.flickr.com/photos/dewittkower/4641701143)．

![4641701143_f5d1785ec4_z.jpg (96.1 kB)](https://img.esa.io/uploads/production/attachments/2063/2015/12/22/3140/6eb10220-a1da-4517-b47d-f9c22516029a.jpg)
[Bletia patula | Flickr - Photo Sharing!](https://www.flickr.com/photos/dewittkower/4641701143)

花言葉は「[**あなたを忘れない**](http://hamakko.info/photo/b/080507.html)」．Promise/Rx wrapperなので丁度いい．あと，裏にはIoTというバズワードに乗っかる各社に対して「Androidのこと忘れんなよ」ってメッセージもある．某スマートグラスのAndroid SDK復活を心よりお祈り申し上げます．


### 利用例
たとえばRxBletiaは`rx.Observable<T>`を喋れるので，Characteristicから読み取った値をRetrofitなクライアントからWeb APIに投げて，返り値をRealmに保存，みたいなことがさくさくっと書ける．

```java
// retrolambdaな記法で書きます
// context, client, requestCharacteristicはどっかで用意してきてね
RxBletia bletia = new RxBletia(context);
bletia.connect()
    .flatMap(_void -> bletia.discoverServices())
    .flatMap(_void -> bletia.readCharacteristic(requestCharacteristic))
    .flatMap(characteristic -> client.get(characteristic.getValue())
    .subscribe(res -> {
        Realm.getDefaultInstance()
            .executeTransaction(realm -> {
                realm.copyToRealm(res);
            });
    });
```

RxじゃないBletiaの方もPromiseを返すので，少なくともややこしいCallback Hellから逃れることは出来る．

みんなもBletia使ってつらくないAndroid用BLEアプリ書こう．PRもお待ちしております．

## References
* [**izumin5210/Bletia**][bletia]
* [AndroidのBLEでCharacteristicsのRead/Writeサンプルを作ってみた - ReDo][youten]
* [kyobashi.dexでAndroidのBLEがつらい話してきた #kyobashidex - うさみみを生やせ] [kyobashi-dex]
* [#potatotips でBLEのつらさを軽減する話してきた - うさみみを生やせ][potatotips]
* [こわくないBLE / BLE is afraid // Speaker Deck][wakate]
* [JDeferred][jdeferred]

[bletia]: https://github.com/izumin5210/Bletia
[jdeferred]: http://jdeferred.org/

[konashi-sdk]: https://github.com/YUKAI/konashi-android-sdk/
[youten]: http://greety.sakura.ne.jp/redo/2013/11/androidblecharacteristicsreadwrite.html
[potatotips]: http://izumin.hateblo.jp/entry/2015/09/23/165945
[kyobashi-dex]: http://izumin.hateblo.jp/entry/2015/09/08/170337
[wakate]: https://speakerdeck.com/izumin5210/ble-is-afraid