onCharacteristicChanged is not called in BluetoothGatt - android

What i am doing:
Connecting my Android app to the device using gatt.connect().
After connecting, i am discovering all the services.
Then, i am enabling the notification on all the control characteristics. It is a successful write.
After that, i am trying to write some data on one of those control characteristics, which is a success.
The expected behavior is that i should receive a reply on onCharacteristicChanged(), but it is not triggering.
Connecting:
mBluetoothGatt = device.connectGatt(mContext, false, mGattCallback);
mDevice = device;
GATT Callback
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
Log.i(Constant.BLUETOOTH_GATT_TAG, "Status: " + status);
super.onConnectionStateChange(gatt, status, newState);
switch (newState) {
case STATE_CONNECTED:
Log.i("gattCallback", "STATE_CONNECTED");
gatt.discoverServices();
break;
}
}
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
services = gatt.getServices();
for (BluetoothGattService service : services) {
Log.i("services Discovered", service.getUuid().toString());
}
BluetoothGattCharacteristic characteristic = gatt.getService(Constant.UUID_FRANK_SERVICE).getCharacteristic(Constant.UUID_ILLUMINATION_CONTROL_POINT_CHARACTERISTICS);
Log.d("Notification Enabled", "" + enableNotificationsForCharacteristic(characteristic));
//getAuthenticated();
}
#Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
Log.d(CHARACTERISTICS_CHANGED_TAG, "Received from Characteristic UUID");
}
#Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
Log.d("onCharacteristicWrite", "Value is written...");
}
#Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorWrite(gatt, descriptor, status);
Log.d("onDescriptorWrite", "Descriptior is written...");
Log.d("onDescriptorWrite" , "" + mBluetoothGatt.readDescriptor(descriptor));
}
#Override
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorRead(gatt, descriptor, status);
Log.d("onDescriptorRead" , "" + status);
}
#Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
}
};
Enabling The Notifications:
private boolean enableNotificationsForCharacteristic(BluetoothGattCharacteristic characteristic) {
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
if (mBluetoothGatt != null) {
mBluetoothGatt.setCharacteristicNotification(characteristic, true);
if (mBluetoothGatt.writeDescriptor(descriptor)) {
return true;
}
}
return false;
}
Writing to Characteristic:
private boolean writeToCharacteristic(BluetoothGattService service, BluetoothGattCharacteristic characteristic, byte[] aValue, boolean aWithResponse) {
boolean ret = false;
if (service != null) {
if (characteristic != null) {
characteristic.setValue(aValue);
characteristic.setWriteType(aWithResponse ? BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT : BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
ret = mBluetoothGatt.writeCharacteristic(characteristic);
} else {
Log.e(TAG, "writeToCharacteristic() - Characteristic is null! " + service + " - " + characteristic);
}
} else {
Log.e(TAG, "writeToCharacteristic() - Service is null! " + service);
}
return ret;
}
What i am expecting:
After setting notification descriptor, i am getting a GATT_SUCCESS but when i am writing a characteristic, it is not triggering onCharacteristicChanged(). I am expecting it to trigger so that i can read the notification response. The device is behaving properly because i have confirmed the notification using Nordic Connect App
What have i tried:
Tried verifying the descriptor, to see if it is being written properly. It does.
Cross checking the name of services and characteristics. They are all fine.
Tried putting delay before write descriptor. It is being written properly.
Can anyone help me? Why it is not triggering onCharacteristicChanged?

Related

Notify and Write characteristic to differents characteristic consecutively

I am trying to receive notifications in a characteristic and then write text in another characteristic of the same BLE device. But when writing to the device most of the time it disconnects me, because something will not go well I imagine. This is the code.
BluetoothGatt gatt = null;
BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
gatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
gatt.close();
}
}
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
BluetoothGattCharacteristic characteristic = null;
if (BLOODGLUCOSE_MODEL.equals(GlobalNames.ADF_B27)) {
characteristic = gatt.getService(BLOODGLUCOSE_SERVICEUDID).getCharacteristic(BLOODGLUCOSE_NOTIFY_CHARACTERISTICSUDID);
gatt.setCharacteristicNotification(characteristic, true);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_UUID);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);
}
}
#Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorWrite(gatt, descriptor, status);
BluetoothGattCharacteristic characteristic = null;
try {
if (BLOODGLUCOSE_MODEL.equals(GlobalNames.ADF_B27)) {
characteristic =
gatt.getService(BLOODGLUCOSE_SERVICEUDID)
.getCharacteristic(BLOODGLUCOSE_WRITE_CHARACTERISTICSUDID);
byte[] byteValue = new byte[10];
byteValue[0] = (byte)0x5A;
byteValue[1] = (byte)0x0A;
byteValue[2] = (byte)0x00;
byteValue[3] = (byte)0x14;
byteValue[4] = (byte)0x09;
byteValue[5] = (byte)0x14;
byteValue[6] = (byte)0x0A;
byteValue[7] = (byte)0x05;
byteValue[8] = (byte)0x09;
byteValue[9] = (byte)0xAF;
characteristic.setValue(byteValue);
(gatt.writeCharacteristic(characteristic);
}
} catch (NullPointerException e) { }
}
}
I can see that writeDescriptor() and writeCharacteristic always returns true.
Does anyone see any errors?
Thanks.

android 10 is not working on BLE Bluetooth connection

android 10 for BLE Bluetooth connection is not connected , i will set all permission also but i get connection status 133 issues ,how to solve this issues ,here i declare the scanning and callback code ,please check and give your idea
but below android 10 version is working fine,only issues on android 10 device ,give an idea to solve the issues
private void scanLeDevice(final boolean enable) {
if (scanner == null) {
scanner = btAdapter.getBluetoothLeScanner();
}
if (scanCallback == null) setScanCallback(null);
scanner.startScan(createScanFilters(),createScanSettings(),scanCallback);
isScanning = true;
}
ScanCallback scanCallback = new ScanCallback() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onScanResult(int callbackType, #NonNull ScanResult scanResult) {
if (connectedDevices.containsKey(scanResult.getDevice().getAddress())) {
return;
}
if (connectingDevices.contains(scanResult.getDevice().getAddress())) {
// If we're already connected, forget it
//Timber.d("Denied connection. Already connecting to " + scanResult.getDevice().getAddress());
return;
}
if (connectionGovernor != null && !connectionGovernor.shouldConnectToAddress(scanResult.getDevice().getAddress())) {
// If the BLEConnectionGovernor says we should not bother connecting to this peer, don't
return;
}
final BluetoothDevice device = btAdapter.getRemoteDevice(scanResult.getDevice().getAddress());
if (device == null) {
Log.e(TAG, "Device not found. Unable to connect.");
}
connectingDevices.add(scanResult.getDevice().getAddress());
// connectToDevice(device);
Timber.d("Initiating connection to " + scanResult.getDevice().getAddress());
device.connectGatt(context, false, mGattCallback, BluetoothDevice.TRANSPORT_LE );
}
#Override
public void onScanFailed(int i) {
Timber.e("Scan failed with code " + i);
}
};
#NonNull
BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
#Override
public void onConnectionStateChange(#NonNull BluetoothGatt gatt, int status, int newState) {
synchronized (connectedDevices) {
// It appears that certain events (like disconnection) won't have a GATT_SUCCESS status
// even when they proceed as expected, at least with the Motorola bluetooth stack
if (status != BluetoothGatt.GATT_SUCCESS)
Timber.w("onConnectionStateChange with newState %d and non-success status %s", newState, gatt.getDevice().getAddress());
Set<BluetoothGattCharacteristic> characteristicSet;
switch (newState) {
case BluetoothProfile.STATE_DISCONNECTING:
Timber.d("Disconnecting from " + gatt.getDevice().getAddress());
characteristicSet = discoveredCharacteristics.get(gatt.getDevice().getAddress());
for (BluetoothGattCharacteristic characteristic : characteristicSet) {
if (notifyUUIDs.contains(characteristic.getUuid())) {
Timber.d("Attempting to unsubscribe on disconneting");
setIndictaionSubscription(gatt, characteristic, false);
}
}
discoveredCharacteristics.remove(gatt.getDevice().getAddress());
break;
case BluetoothProfile.STATE_DISCONNECTED:
Timber.d("Disconnected from " + gatt.getDevice().getAddress());
connectedDevices.remove(gatt.getDevice().getAddress());
connectingDevices.remove(gatt.getDevice().getAddress());
if (transportCallback != null)
transportCallback.identifierUpdated(BLETransportCallback.DeviceType.CENTRAL,
gatt.getDevice().getAddress(),
Transport.ConnectionStatus.DISCONNECTED,
null);
characteristicSet = discoveredCharacteristics.get(gatt.getDevice().getAddress());
if (characteristicSet != null) { // Have we handled unsubscription on DISCONNECTING?
for (BluetoothGattCharacteristic characteristic : characteristicSet) {
if (notifyUUIDs.contains(characteristic.getUuid())) {
Timber.d("Attempting to unsubscribe before disconnet");
setIndictaionSubscription(gatt, characteristic, false);
}
}
} else
if ( status != BluetoothGatt.GATT_SUCCESS ) {
if ( status == 133) {
refreshDeviceCache(gatt);
}
}
gatt.close(); discoveredCharacteristics.remove(gatt.getDevice().getAddress());
break;
case BluetoothProfile.STATE_CONNECTED:
boolean mtuSuccess = gatt.requestMtu(BLETransport.DEFAULT_MTU_BYTES);
Timber.d("Connected to %s. Requested MTU success %b", gatt.getDevice().getAddress(),
mtuSuccess);
break;
}
super.onConnectionStateChange(gatt, status, newState);
}
}
#Override
public void onMtuChanged(#NonNull BluetoothGatt gatt, int mtu, int status) {
Timber.d("Got MTU (%d bytes) for device %s. Was changed successfully: %b",
mtu,
gatt.getDevice().getAddress(),
status == BluetoothGatt.GATT_SUCCESS);
mtus.put(gatt.getDevice().getAddress(), mtu);
// TODO: Can we craft characteristics and avoid discovery step?
boolean discovering = gatt.discoverServices();
Timber.d("Discovering services : " + discovering);
}
#Override
public void onServicesDiscovered(#NonNull BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS)
Timber.d("Discovered services");
else
Timber.d("Discovered services appears unsuccessful with code " + status);
// TODO: Keep this here to examine characteristics
// eventually we should get rid of the discoverServices step
boolean foundService = false;
try {
List<BluetoothGattService> serviceList = gatt.getServices();
for (BluetoothGattService service : serviceList) {
if (service.getUuid().equals(serviceUUID)) {
Timber.d("Discovered Service");
foundService = true;
HashSet<BluetoothGattCharacteristic> characteristicSet = new HashSet<>();
characteristicSet.addAll(service.getCharacteristics());
discoveredCharacteristics.put(gatt.getDevice().getAddress(), characteristicSet);
for (BluetoothGattCharacteristic characteristic : characteristicSet) {
if (notifyUUIDs.contains(characteristic.getUuid())) {
setIndictaionSubscription(gatt, characteristic, true);
}
}
}
}
if (foundService) {
synchronized (connectedDevices) {
connectedDevices.put(gatt.getDevice().getAddress(), gatt);
}
connectingDevices.remove(gatt.getDevice().getAddress());
}
} catch (Exception e) {
Timber.d("Exception analyzing discovered services " + e.getLocalizedMessage());
e.printStackTrace();
}
if (!foundService)
Timber.d("Could not discover chat service!");
super.onServicesDiscovered(gatt, status);
}
/**
* Subscribe or Unsubscribe to/from indication of a peripheral's characteristic.
*
* After calling this method you must await the result via
* {#link #onDescriptorWrite(BluetoothGatt, BluetoothGattDescriptor, int)}
* before performing any other peripheral actions.
*/
private void setIndictaionSubscription(#NonNull BluetoothGatt peripheral,
#NonNull BluetoothGattCharacteristic characteristic,
boolean enable) {
boolean success = peripheral.setCharacteristicNotification(characteristic, enable);
Timber.d("Request notification %s %s with sucess %b", enable ? "set" : "unset", characteristic.getUuid().toString(), success);
BluetoothGattDescriptor desc = characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG);
desc.setValue(enable ? BluetoothGattDescriptor.ENABLE_INDICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
boolean desSuccess = peripheral.writeDescriptor(desc);
Timber.d("Wrote descriptor with success %b", desSuccess);
}
#Override
public void onDescriptorWrite(#NonNull BluetoothGatt gatt, #NonNull BluetoothGattDescriptor descriptor,
int status) {
Timber.d("onDescriptorWrite");
if (status == BluetoothGatt.GATT_SUCCESS && transportCallback != null) {
if (Arrays.equals(descriptor.getValue(), BluetoothGattDescriptor.ENABLE_INDICATION_VALUE)) {
transportCallback.identifierUpdated(BLETransportCallback.DeviceType.CENTRAL,
gatt.getDevice().getAddress(),
Transport.ConnectionStatus.CONNECTED,
null);
} else if (Arrays.equals(descriptor.getValue(), BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE)) {
Timber.d("disabled indications successfully. Closing gatt");
gatt.close();
}
}
}
#Override
public void onCharacteristicChanged(#NonNull BluetoothGatt gatt, #NonNull BluetoothGattCharacteristic characteristic) {
Timber.d("onCharacteristicChanged %s with %d bytes", characteristic.getUuid().toString().substring(0,5),
characteristic.getValue().length);
if (transportCallback != null)
transportCallback.dataReceivedFromIdentifier(BLETransportCallback.DeviceType.CENTRAL,
characteristic.getValue(),
gatt.getDevice().getAddress());
super.onCharacteristicChanged(gatt, characteristic);
}
#Override
public void onCharacteristicWrite(#NonNull BluetoothGatt gatt,
#NonNull BluetoothGattCharacteristic characteristic, int status) {
Timber.d("onCharacteristicWrite with %d bytes", characteristic.getValue().length);
Exception exception = null;
if (status != BluetoothGatt.GATT_SUCCESS) {
String msg = "Write was not successful with code " + status;
Timber.w(msg);
exception = new UnknownServiceException(msg);
}
if (transportCallback != null)
transportCallback.dataSentToIdentifier(BLETransportCallback.DeviceType.CENTRAL,
characteristic.getValue(),
gatt.getDevice().getAddress(),
exception);
}
#Override
public void onReadRemoteRssi(#NonNull BluetoothGatt gatt, int rssi, int status) {
super.onReadRemoteRssi(gatt, rssi, status);
}
};
now the app is working for change the bluetooth device support type
device.connectGatt(context, false, mGattCallback, BluetoothDevice.DEVICE_TYPE_LE);
but now the app is not working on huawei device , if any have idea for the device huawei for this issue

Can't read Heart Rate in Xiaomi Band 2

I was trying to read Heart Rate values from my Xiaomi Band 2. For this I tried using and adapting BluetoothLeGatt project from https://github.com/android/connectivity-samples/tree/master/BluetoothLeGatt .
So far I was able to survey the BLE devices nearby. After that I selected Xiaomi Band 2 and I could successfully list out all the services this device had, including Heart Rate Service. Inside Heart Rate Service I found the characteristic Heart Rate Measurement that I was looking for.
I tried to print data from this characteristic without success. I was unable to see any data in my log, even though I made some slight changes.
This is my LEScanCallback (with the slight changes done)
// Implements callback methods for GATT events that the app cares about. For example,
// connection change and services discovered.
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.i(TAG, "Connected to GATT server.");
// Attempts to discover services after successful connection.
Log.i(TAG, "Attempting to start service discovery:" +
mBluetoothGatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
}
}
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
BluetoothGattCharacteristic characteristic =
gatt.getService(HEART_RATE_SERVICE_UUID)
.getCharacteristic(HEART_RATE_MEASUREMENT_CHAR_UUID);
System.out.println("HEART_RATE_MEASUREMENT_CHAR_UUID: "+HEART_RATE_MEASUREMENT_CHAR_UUID);
/*gatt.setCharacteristicNotification(characteristic, true);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_UUID);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
gatt.writeDescriptor(descriptor); */
setCharacteristicNotification(characteristic,true);
}
#Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
System.out.println("onCharacteristicRead: " + Arrays.toString(characteristic.getValue()));
}
#Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status){
super.onDescriptorWrite(gatt, descriptor, status);
System.out.println("onDescriptorWrite");
BluetoothGattCharacteristic characteristic = gatt.getService(HEART_RATE_SERVICE_UUID)
.getCharacteristic(HEART_RATE_MEASUREMENT_CHAR_UUID);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
characteristic.setValue(new byte[]{1, 1});
//gatt.writeCharacteristic(characteristic);
boolean success = gatt.readCharacteristic(characteristic);
System.out.println("success? "+success);
System.out.println("status: "+status);
}
#Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
System.out.println("onCharacteristicChanged: " + Arrays.toString(characteristic.getValue()));
}
};
I don't get to the point onCharacteristicRead() or onCharacteristicChanged() is called. I believe it's because gatt.readCharacteristic(characteristic) is FALSE and status is 3 (GATT_WRITE_NOT_PERMITTED) in onDescriptorWrite() function.
Can somebody help me figuring out the problem? I'm starting to lose all hope...

onCharacteristicChanged is not called after writing on ble

I need some response data from Ble. When I am writing something on ble I need to read response data from Ble. I am able to successfully enable and disable my ble device but only missing response data from ble. I also need to convert decimal time into Integer hex format like for 60 min into 0x3c.
private BluetoothGattCallback gattCallback= new BluetoothGattCallback() {
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt,status);
clientGatt =gatt;
if (status == BluetoothGatt.GATT_SUCCESS) {
BluetoothGattService service = gatt.getServices().get(2);
List<BluetoothGattCharacteristic> gattCharacteristics = service.getCharacteristics();
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
if (gattCharacteristic.getUuid().toString().equalsIgnoreCase(AppConstant.RECEIVE_UUID)) {
readCharacteristic=gattCharacteristic;
}
if (gattCharacteristic.getUuid().toString().equalsIgnoreCase(AppConstant.SEND_UUID_STR)) {
writeCharacteristic = gattCharacteristic;
}
}
}
}
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
#Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt,characteristic,status);
LogUtils.errorLog("onCharacteristicRead", "##: "+characteristic.getValue()[0]);
}
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
#Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic)
}
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
#Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
setCharacteristicNotification(characteristic,true);
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
clientGatt = gatt;
switch (newState) {
case BluetoothProfile.STATE_CONNECTED:
isBLE_Connected=true;
gatt.discoverServices();
break;
case BluetoothProfile.STATE_DISCONNECTED:
isBLE_Connected=false;
if(status==133 || status==22 || status==62){
refreshDeviceCache();
clientGatt.discoverServices();
}else{
clientGatt.disconnect();
clientGatt.close();
}
break;
}
}
};
Before onCharacteristicChanged is called you had to enable notification.
Someting like:
//Enable local notifications
gatt.setCharacteristicNotification(characteristic, true);
//Enabled remote notifications
BluetoothGattDescriptor desc =characteristic.getDescriptor(CONFIG_DESCRIPTOR);
desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(desc);
should help.
You when you write something on characteristic with the help of BluetoothGattDescriptor as
Mike's answer
You need to override the following method to listen to the changes has been completed then you can read the characteristics:
#Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorWrite(gatt, descriptor, status);
Log.d(TAG, "onDescriptorWrite :" + ((status == BluetoothGatt.GATT_SUCCESS) ? "Sucess" : "false"));
}

Nexus 9 in Peripheral mode is not accepting connection from clients or not responding to client requests?

I am using Nexus 9 in peripheral mode. I have created a instance of GATT server:
mGattServer = mBluetoothManager.openGattServer(this, mBluetoothGattServerCallback);
I have created a BluetoothGattService & BluetoothGattCharacteristic.
Added service to GATT server & characteristic to service.
BluetoothGattService service =new BluetoothGattService(SERVICE_UUID,
BluetoothGattService.SERVICE_TYPE_PRIMARY);
BluetoothGattCharacteristic offsetCharacteristic =
new BluetoothGattCharacteristic(CHARACTERISTIC_NUM_UUID,
//Read+write permissions
BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE,
BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);
service.addCharacteristic(offsetCharacteristic);
mGattServer.addService(service);
Instance of BluetoothGattServerCallBack:
private BluetoothGattServerCallback mBluetoothGattServerCallback = new BluetoothGattServerCallback() {
#Override
public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
//super.onConnectionStateChange(device, status, newState);
Log.i(TAG, "onConnectionStateChange "
+ getStatusDescription(status) + " "
+ getStateDescription(newState));
if (newState == BluetoothProfile.STATE_CONNECTED) {
Log.i(TAG, "Connected..");
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
Log.i(TAG, "Disconnected..");
}
}
#Override
public void onServiceAdded(int status, BluetoothGattService service) {
//super.onServiceAdded(status, service);
Log.i(TAG, "onServiceAdded");
}
#Override
public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value);
Log.i(TAG, "onCharacteristicWriteRequest");
}
#Override
public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
Log.i(TAG, "onCharacteristicReadRequest");
}
#Override
public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
super.onDescriptorReadRequest(device, requestId, offset, descriptor);
Log.i(TAG, "onDescriptorReadRequest");
}
#Override
public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite, responseNeeded, offset, value);
Log.i(TAG, "onDescriptorWriteRequest");
}
#Override
public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
super.onExecuteWrite(device, requestId, execute);
Log.i(TAG, "onExecuteWrite");
}
#Override
public void onNotificationSent(BluetoothDevice device, int status) {
super.onNotificationSent(device, status);
Log.i(TAG, "onNotificationSent");
}
};
Now when I am trying to connect a GATT client to this server, onConnectionStateChange() method of BluetoothGattServerCallback never invoked.
Code from Client Side app:
To connect to GATT server running on Nexus 9
mConnectedGatt = device.connectGatt(this, false, mGattCallback);
Instance of BluetoothGattCallback:
private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED) {
Log.i(TAG, "Connected to server");
gatt.discoverServices();
} else if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_DISCONNECTED) {
Log.i(TAG, "Disconnected from server");
} else if (status != BluetoothGatt.GATT_SUCCESS) {
gatt.disconnect();
}
}
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
}
#Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
}
#Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
}
#Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
}
#Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
}
};
Device(Nexus 9) is discoverable & I am getting it in onLeScan(). But when I am trying to connect to GATT server running on Nexus 9, status in onConnectionStateChange it always STATE_DISCONNECTED.
I tried to connect from some third party applications like "B-BLE", "BLE Scanner", "Bluetooth 4.0 Explorer". Nexus 9 is discoverable in these applications but when I am trying to connect to GATT server, status in onConnectionStateChange() is always STATE_DISCONNECTED.
Any type of help will be appreciated.
Thanks in advance.
As a first step, check if the addService(..) method returns true - only then has the service successfully been added.
Also, try removing the GATT_SUCCESS check from the onConnectionStateChange() method. As far as I know you don't need to test for this there...

Categories

Resources