Reputation: 25
BLE device gets the data when it is disconnected from the gatt server. I am trying to send data to the BLE device through the GATT server. When I try to send data which is command (string) to the BLE device, gattscancallback is called and it says write successful but nothing happens to the BLE device. But when I exit the application, the BLE device gets the data. I found that BLE device gets the data when it is disconnected to the gatt server. How do I solve this problem? this is my GattCallback
private val gattCallback: BluetoothGattCallback = object : BluetoothGattCallback() {
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
super.onConnectionStateChange(gatt, status, newState)
if( status == BluetoothGatt.GATT_FAILURE ) {
disconnect()
return
} else if( status != BluetoothGatt.GATT_SUCCESS ) {
disconnect()
return
}
if( newState == BluetoothProfile.STATE_CONNECTED ) {
// update the connection status message
Log.d(TAG, "Connected to the GATT server")
gatt.discoverServices()
} else if ( newState == BluetoothProfile.STATE_DISCONNECTED ) {
disconnect()
}
}
override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
super.onServicesDiscovered(gatt, status)
// check if the discovery failed
if (status != BluetoothGatt.GATT_SUCCESS) {
Log.e(TAG, "Device service discovery failed, status: $status")
return
}
// log for successful discovery
Log.d(TAG, "Services discovery is successful")
isStatuschanged = "connected"
// find command characteristics from the GATT server
val respCharacteristic = gatt?.let { BluetoothUtils.findResponseCharacteristic(it) }
// disconnect if the characteristic is not found
if( respCharacteristic == null ) {
Log.e(TAG, "Unable to find cmd characteristic")
disconnect()
return
}
gatt.setCharacteristicNotification(respCharacteristic, true)
// UUID for notification
val descriptor: BluetoothGattDescriptor = respCharacteristic.getDescriptor(
UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG)
)
descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
gatt.writeDescriptor(descriptor)
}
override fun onCharacteristicChanged(
gatt: BluetoothGatt?,
characteristic: BluetoothGattCharacteristic
) {
super.onCharacteristicChanged(gatt, characteristic)
//Log.d(TAG, "characteristic changed: " + characteristic.uuid.toString())
readCharacteristic(characteristic)
}
override fun onCharacteristicWrite(
gatt: BluetoothGatt?,
characteristic: BluetoothGattCharacteristic?,
status: Int
) {
super.onCharacteristicWrite(gatt, characteristic, status)
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.d(TAG, "Characteristic written successfully")
} else {
Log.e(TAG, "Characteristic write unsuccessful, status: $status")
disconnect()
}
}
override fun onCharacteristicRead(
gatt: BluetoothGatt?,
characteristic: BluetoothGattCharacteristic,
status: Int
) {
super.onCharacteristicRead(gatt, characteristic, status)
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.d(TAG, "Characteristic read successfully")
readCharacteristic(characteristic)
} else {
Log.e(TAG, "Characteristic read unsuccessful, status: $status")
// Trying to read from the Time Characteristic? It doesnt have the property or permissions
// set to allow this. Normally this would be an error and you would want to:
// disconnectGattServer()
}
}
/**
* Log the value of the characteristic
* @param characteristic
*/
}
this is my write function
fun write(message: String) {
val cmdCharacteristic = BluetoothUtils.findCommandCharacteristic(bluetoothGatt!!)
if (cmdCharacteristic == null) {
Log.e(TAG, "Unable to find cmd characteristic")
disconnect()
return
}
cmdCharacteristic?.value = message.toByteArray()
//bluetoothGatt!!.writeCharacteristic(cmdCharacteristic)
val success: Boolean = bluetoothGatt!!.writeCharacteristic(cmdCharacteristic)
if (!success) {
Log.d("jay", "failed to write command")
}
Log.d("jay", "write succesful")
//disconnect()
}
this is my disconnect function
fun disconnect() {
Log.d("jay", "disconnect: bluetoothGatt is null? ${bluetoothGatt == null}")
bluetoothDeviceAddress = null
bluetoothGatt?.disconnect()
isStatuschanged = "disconnected"
bluetoothGatt = null
}
Upvotes: 2
Views: 421
Reputation: 24
Can you show the disconnect()
method? Because if you wrote that your central device sends data to the ble device when the application closes, it means that gattCallback's onConnectionState
is triggered with a call to newState == BluetoothProfile.STATE_DISCONNECTED
and a call to the disconnet()
method.
Perhaps the problem is that you explicitly need to specify the record type for the characteristic for example: BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT
or BluetoothGattCharacteristic.WRITE_TYPE_WITHOUT_RESPONSE
.
Also, there may be an error in the calling code, for example, if you use coroutines and manage them incorrectly
I recently had a similar problem when I solved it by specifying the feature write type and adding the setCharacteristicNotification()
method
I had a similar problem recently, but I solved it by specifying the feature record type, and adding the setCharacteristicNotification method
Upvotes: 0