複数のCharacteristicsでNotificationを受け取る

ダメな方法

descriptorを登録する際に以下のように続けて登録すると後に登録した方のnotificatinoが受け取れなくなってしまいます。

2つの間にsleepなどの処理を入れても結果は同じでした。

2つのcharacteristicでnotificationを受け取る際には1つ目が完全に書き込み完了した後に改めて書き込みをしてあげる必要があるようです。

        var character: BluetoothGattCharacteristic = service.getCharacteristic(Consts.VERSION_CONTROL)
        device.setCharacteristicNotification(character, true)
        val descriptor = character.getDescriptor(Consts.DESCRIPTER)
        descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
        device.writeDescriptor(descriptor)

        var character2: BluetoothGattCharacteristic = service.getCharacteristic(Consts.ID_INFORMATION)
        device.setCharacteristicNotification(character2, true)
        val descriptor2 = character2.getDescriptor(Consts.DESCRIPTER)
        descriptor2.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
        device.writeDescriptor(descriptor2)

解決策

descriptorを登録するとonDescriptorWriteメソッドが呼ばれますがその中で2つ目のCharacteristicを登録することで2つのNotificationを受け取ることができます。

そのままだと何度も呼ばれてしまうので応急処置としてflugを入れて管理をしています。もっと良い書き方があると思うのですが思いつかなかったのでflugで何度も呼ばれないようにしています。

     〜省略〜
        //1度目の登録
     var character: BluetoothGattCharacteristic = service.getCharacteristic(Consts.VERSION_CONTROL)
        device.setCharacteristicNotification(character, true)
        val descriptor = character.getDescriptor(Consts.DESCRIPTER)
        descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
        device.writeDescriptor(descriptor)
     〜省略〜

    override fun onDescriptorWrite(gatt: BluetoothGatt?, descriptor: BluetoothGattDescriptor?, status: Int) {
        super.onDescriptorWrite(gatt, descriptor, status)
        this.gatt = gatt

        if (flg) {
            return
        }
        flg = true
        //2度目の登録
        var character2: BluetoothGattCharacteristic = this.gatt!!.getService(Consts.PRIMARY_SERVICE).getCharacteristic(Consts.ID_INFORMATION)
        this.gatt!!.setCharacteristicNotification(character2, true)
        val descriptor2 = character2.getDescriptor(Consts.DESCRIPTER)
        descriptor2.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
        this.gatt!!.writeDescriptor(descriptor2)
    }

次の記事

Kotlinでenumerated