Android Bluetooth Low Energy (BLE) vol.5

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

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

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

…の続き。

前回、
サービスやらキャラクタリスティックを得ることが出来ました。

実際通信をする前に、
プロパティを見てみましょう。


11.GATT通信プロパティ

GATTサービスのプロパティなのですが、
・「READ」
・「WRITE」
・「NOTIFY」
この3つが御三家かなと思います。
他にもありますが、今回は触れません。
デバイスの仕様で、上記3つ以外があまりない感じでしたので。

名前から想像するに…
まぁそのままですねw

大体どの仕様書をみても、
各キャラクタリスティックで
利用可能なプロパティが書いてあるはずです。

■「READ」について

GATTクラスにて、
読み込みたいキャラクタリスティックを渡します。

読み取りコマンド発行

final int properties = characteristic.getProperties();
if ((properties & BluetoothGattCharacteristic.PROPERTY_READ) == 0)
    return;

gatt.readCharacteristic(characteristic);

※読み込みのプロパティを確認

結果は、
「BluetoothGattCallback.onCharacteristicRead」
メソッドに来ます。

@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    if (status == BluetoothGatt.GATT_SUCCESS) {
        // 結果
    }
}

■「WRITE」について

GATTクラスに
書き込みたいキャラクタリスティックを渡します。

また、プロパティに関して、
「NOTIFY」・「WRITE」のセットが多い感じがしました。

まず「NOTIFY」で通知をオンに。
次に「WRITE」でコマンド送信。
で、
デバイスが処理し終わった後、
処理結果が通知される仕組みです。
※「NOTIFY」は後述

書き込みコマンド発行
固有コマンドがある場合は、setValueを利用して設定する。

characteristic.setValue([byte command]);


final int properties = characteristic.getProperties();
if ((properties & (BluetoothGattCharacteristic.PROPERTY_WRITE)) == 0)
    return;
gatt.writeCharacteristic(characteristic);

結果は
「BluetoothGattCallback.onCharacteristicWrite」に来ます。

@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    if (status == BluetoothGatt.GATT_SUCCESS) {
        // 成功
    }
}

「BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE」
のプロパティがある場合は、キャラクタリスティックにデータが入っていません。
なので、処理後に通知されるわけです。

■「NOTIFY」について

データを非同期で受け取る定番プロパティです。
要するに、
デバイスの保持している値が変わったら通知するよ~。
ってな機能です。

利用するのはこれ!
CLIENT CHARACTERISTIC CONFIG DESCRIPTOR UUID
「00002902-0000-1000-8000-00805f9b34fb」
※頭文字で「CCCD」と書かれてることが多いです

GATTクラスに
通知させたいキャラクタリスティックのディスクリプタを書き込みます。

final int properties = characteristic.getProperties();
if ((properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) == 0)
    return; // 通知必須

gatt.setCharacteristicNotification(characteristic, true);

final BluetoothGattDescriptor descriptor = characteristic.getDescriptor("00002902-0000-1000-8000-00805f9b34fb");
if (descriptor != null) {
    descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
    gatt.writeDescriptor(descriptor);
}

これで通知モード開始です。

で、値が変更された時に
「BluetoothGattCallback.onCharacteristicChanged」が呼び出されます。

@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
    // お目当てのデータは、characteristic.getValue() で取得できるはず
}

※「onCharacteristicRead」で値が来た際に、
そのまま「onCharacteristicChanged」を呼んでしまえばここに処理を集約出来ます

通知を止める方法も載せておきます。
まぁ、逆やればいいんですが…
※意外と掲載していないサイトが多い

final int properties = characteristic.getProperties();
if ((properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) == 0)
    return;

gatt.setCharacteristicNotification(characteristic, false);

final BluetoothGattDescriptor descriptor = characteristic.getDescriptor("00002902-0000-1000-8000-00805f9b34fb");
if( descriptor != null ) {
    descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
    gatt.writeDescriptor(descriptor);
}

これでOKです。

vol.6へ続く

それでは。

azjuke

投稿者: azjuke

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