Android Bluetooth Low Energy (BLE) vol.4

こんにちは、あじゅ~くです。

さて、
本日からBLE特集です。
※2017/03/22 時点の記事

BLEの記事はこちら
vol.1
vol.2
vol.3
vol.5
vol.6

…の続き。

先週、
お目当てのデバイスを発見する!
というところまでやりました。

実際に接続してみましょう!


7.GATT接続

いよいよ、デバイスと接続します。

場合によっては、
・キャッシュをリフレッシュ
・Bluetooth関連のブロードキャスト登録
を行いましょう。

利用するのはこちら。

・BluetoothDevice.connectGatt
・BluetoothGattCallback 抽象クラス

・BluetoothGattCallback.onConnectionStateChange
・BluetoothGattCallback.onServicesDiscovered

接続メソッド
「BluetoothDevice.connectGatt」に
「BluetoothGattCallback」を継承したクラスを渡して
接続処理を開始します。

// メンバ定義
BluetoothGatt _gatt;

// GATT接続
_gatt = BluetoothDevice.connectGatt(Context, boolean, BluetoothGattCallback)

このような感じにします。
メンバ変数「_gatt」は
後々、データのやり取りに使用します。


8.デバイス接続通知受信

接続出来た場合、
「BluetoothGattCallback.onConnectionStateChange」に
通知が来ます。

※この接続通知は時間がかかることがあります。

@Override
public void onConnectionStateChange(final BluetoothGatt gatt, final int status, final int newState) {
    if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED) {
        // 接続
    }
    else {
        if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            // 切断
        }
        // 不明なエラー
    }
    super.onConnectionStateChange(gatt, status, newState);
}

接続出来た場合は、
該当箇所でサービスディスカバリを行います。


9.サービスディスカバリ開始

サービスディスカバリを行います。

@Override
public void onConnectionStateChange(final BluetoothGatt gatt, final int status, final int newState) {
    if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED) {
        // 接続
        // サービスディスカバリを行う
        if( !gatt.discoverServices() ) {
            // 失敗
        }
    }
    else {
        if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            // 切断
        }
        // 不明なエラー
    }
    super.onConnectionStateChange(gatt, status, newState);
}

これだけです。
対象デバイスが、
どのようなサービスを保持しているのか通知を待ちましょう。

サービスディスカバリを行う際に、
ウエイトを少しかけたほうがいいかもしれません。

私のライブラリはここで、
(メインスレッド)ハンドラを利用して
「500ms」ほどウエイトしてから
「discoverServices」をコールしています。


10.サービスディスカバリ通知受信

GATTサービスのリストが取得出来ればOKです。
これでデバイスがどの機能を保持しているか?
・GATTサービス
・GATTサービスのキャラクタリスティック
が分かります。

@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
    if (_gatt != gatt) {
        // メンバのGATTと違う...
        return;
    }
    final List<BluetoothGattService> listService = gatt.getServices();
    if (listService == null) {
        // GATTサービス見つからない(エラー)
        return;
    }
    // GATTサービスを列挙
    for (final BluetoothGattService service : listService) {
        if ((service == null) || (service.getUuid() == null))
            continue;

        // GATTサービスのキャラクタリスティックを列挙
        List<BluetoothGattCharacteristic> listCharacteristic = service.getCharacteristics();
        for (BluetoothGattCharacteristic characteristic : listCharacteristic) {
            // 利用したいものがあるはず!
        }
    }
}

共通の仕様で、
デバイス情報やバッテリー情報もここで列挙出来ます。
大体持ってますので、この辺もうまく使いましょう。

また、
サービスとキャラクタリスティックは
利用しやすいように保管しておくといいです。
(ここらは、よしなにどうぞ)
例えば、
リストやマップにポインタを保管しとくとかね。

…vol.5へ続く

それでは。

azjuke

投稿者: azjuke

神奈川県横浜市在住 何かよくわからないブログに変身中! 色々な話題振りまいていきますよ。