Reputation: 371
I have a one Android Phone acting as Central Device and another Android Phone acting as Peripheral.
From Central, I'm making a request to read characteristic of Peripheral, using mBluetoothGatt.readCharacteristic ( characteristic )
Onto the peripheral, the method
void onCharacteristicReadRequest ( // Bluetooth GATT Server Callback Method
BluetoothDevice device,
int requestId,
int offset,
BluetoothGattCharacteristic characteristic
)
invokes, and there I'm doing two things:
1. Initializing a byte [] value
to store String in byte
form.
2. Sending response to the Client using method mGattServer.sendResponse()
.
@Override public void onCharacteristicReadRequest (
BluetoothDevice device, int requestId, int offset,
BluetoothGattCharacteristic characteristic ) {
super.onCharacteristicReadRequest ( device, requestId, offset, characteristic );
String string = "This is a data to be transferred";
byte[] value = string.getBytes ( Charset.forName ( "UTF-8" ) );
mGattServer.sendResponse ( device, requestId, BluetoothGatt.GATT_SUCCESS, 0, value );
}
My problem here is that above method gets called multiple times when I have made a read request once from the Central device.
Due to this, I'm getting the data on the Central device as something like
This is a data to be transferredThis is a data to be transferredThis is a...
I have also tried with other characteristics. But for those, callback method gets called once.
Can you point me where I am doing wrong?
EDIT: From Peripheral, I have debugged that I am sending 32-bytes of data.
When I change string
value from This is a data to be transferred
to DATA
, the method onCharacteristicReadRequest()
calls one time only.
Further experiments with the field string
have led me to the conclusion that maximum amount of bytes to be sent in the response is 21-bytes.
If this is the case, then how should I send the response from the GATT Server, so that Central Device can obtain exact data only?
Upvotes: 4
Views: 2831
Reputation: 1
when onCharacteristicReadRequest be invoked, You should judge whether the characteristic you are about to read is you want:
void onCharacteristicReadRequest ( // Bluetooth GATT Server Callback Method
BluetoothDevice device,
int requestId,
int offset,
BluetoothGattCharacteristic characteristic
)
Upvotes: 0
Reputation: 419
In android how you do for big text
private String data = "123456789123456789123xx";
Let above being your text
Then following will be implementation of onCharacteristicReadRequest()
@Override
public void onCharacteristicReadRequest(BluetoothDevice device,
int requestId, int offset,
BluetoothGattCharacteristic characteristic) {
super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
byte value[] = data.getBytes();
value = Arrays.copyOfRange(value,offset,value.length);
gattServer.sendResponse ( device, requestId,
BluetoothGatt.GATT_SUCCESS, offset, value );
}
So basically in every call offset amount of data is transferred so in next calls to this method you should send only offset, to length of data
this is same as what @Вадзім Жукоўскі said, but for C#
Thanks @Вадзім Жукоўскі for pointing this out
Upvotes: 3
Reputation: 11
This from C#, but I think it can help. When you transfer a large array of bytes, you need to use offset. Otherwise, as in your case, you constantly start transferring your array from the beginning. Offset changes automatically. You just need to use it to offset the array when reading the next piece of data.
byte[] result = DataBytes.Skip(offset).ToArray();
mGattServer.SendResponse(device, requestId, GattStatus.Success, offset, result);
Upvotes: 1