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!
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.