Home > Mobile >  How to write and receive to and from a ble device in Kotlin?
How to write and receive to and from a ble device in Kotlin?

Time:01-21

So I have a bluetooth class written in Kotlin where I search for a ble device, find it, connect to it and discover it's services, so far so good. Now I am also trying to write data to that device and read data from it (notifying channel). The tricky part is that I have to send data to receive data so that is why I am asking for write as well as read implementation, because if one doesn't work and the other does I still would have no idea either of them work.In swift I use Peripheral?.writeValue(data, for writeCharacteristic, type: .withoutResponse), I am looking to something similar to this for writing and the delegate for reading

func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error {     data = notifyCharacteristic.value}

So far I have this in Kotlin to try to achieve a similar result as in swift. Of course I have looked up tutorials and documentation, but to no avail. This is the code I use:

override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
    
    if (status == BluetoothGatt.GATT_SUCCESS) {
        for (service in gatt?.services ?: emptyList()) {
            for (characteristic in service.characteristics) {
                if (characteristic.properties and BluetoothGattCharacteristic.PROPERTY_READ != 0) {
                    /*readCharacteristic = characteristic*/
                    /*  Log.v("Bluetooth: Services discovered", "Read characteristic!! $readCharacteristic")*/
                }
                if (characteristic.properties and BluetoothGattCharacteristic.PROPERTY_WRITE != 0) {
                    writeCharacteristic = characteristic

                    Log.v(
                        "Bluetooth: Services discovered",
                        "Write characteristic ${characteristic.uuid}"
                    )
                }
                if (characteristic.properties and BluetoothGattCharacteristic.PROPERTY_NOTIFY != 0) {
                    notifyCharacteristic = characteristic
                    Log.v(
                        "Bluetooth: Services discovered",
                        "Notify characteristic $notifyCharacteristic"
                    )
                    gatt?.setCharacteristicNotification(characteristic, true)
                }
            }
        }
    }
}
override fun onCharacteristicRead(
    gatt: BluetoothGatt,
    characteristic: BluetoothGattCharacteristic,
    value: ByteArray,
    status: Int
) {
    super.onCharacteristicRead(gatt, characteristic, value, status)
    Log.v("Data received!!", "Data: $value")
}
override fun onCharacteristicChanged(
            gatt: BluetoothGatt?,
            characteristic: BluetoothGattCharacteristic?
        ) {

            Log.i("Notification", "Notification state changed")

        }

and most importantly the write function

fun write() {
    val value = byteArrayOf(
        0x02.toByte(),
        0x03.toByte(),
        0x24.toByte(),
        0x65.toByte(),
        0x01.toByte(),
        0xBE.toByte(),
        0xF8.toByte(),
        0x03.toByte()
    )


    writeCharacteristic?.setValue(value)
    writeCharacteristic?.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE
    gatt?.writeCharacteristic(writeCharacteristic)
    Log.v("ble write", "try ble write ${writeCharacteristic?.uuid}")

I have tried several things here, because setValue is depreciated, but I couldn't find what I should use instead. The writeCharacteristic and notifyCharacteristic have the correct uuid.

Thanks in advance!

CodePudding user response:

In Android, you need to also write the Client Characteristic Configuration Descriptor yourself, because Android's bluetooth stack doesn't do that for you, when you enable notifications.

See https://stackoverflow.com/a/41377476.

  • Related