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.