Vit Bernatik Vit Bernatik - 1 month ago 7x
Android Question

Android Central with GattServer

I'm trying to program Bluetooth low energy - AlertNotificationService (ANS). It is a bit weird service because typically services run on GAP peripheral. But ANS run on GAP central. So typical way of working shall be for example this:

Watch - GAP peripheral (broadcasting), GATT client
Phone - GAP central , GATT server

Basically it works for me but not always. And this instability is very strange to me. When I look with bluetooth LE analyzer I see that Android GATT server sometimes tells there are no characteristic in my profile...

It looks like this: "watch" ask for my GATT service (I know it is proprietary not ANS UUID)

Slave->Master ATT Rcvd Find By Type Value Request, GATT Primary Service Declaration 11:22:33:44:11:22:33:44:11:76:62:65:01:00:00:00

Phone says the service is there starting from handle 0x35

Master->Slave ATT Rcvd Find By Type Value Response Handle: 0x0035

Watch ask for charactersitisc from handle 0x35

Slave->Master ATT Rcvd Read By Type Request, GATT Characteristic Declaration, Handles: 0x0035..0xffff

But phone sometimes incorrectly says that there is no characteristic from that handle:

Master->Slave ATT Rcvd Error Response - Attribute Not Found, Handle: 0x0035

When I do add service and characteristic into GATT server I always get "true" from functions. I do it like this:

BluetoothGattService service =new BluetoothGattService(Vbe_AnsExt.UUID_SERVICE,

BluetoothGattCharacteristic characApp =
new BluetoothGattCharacteristic(Vbe_AnsExt.UUID_CharacApp,
BluetoothGattCharacteristic.PROPERTY_READ ,

BluetoothGattCharacteristic characMsg =
new BluetoothGattCharacteristic(Vbe_AnsExt.UUID_CharacMsg,
BluetoothGattCharacteristic.PROPERTY_READ ,
BluetoothGattCharacteristic.PERMISSION_READ );

boolean ret;
ret = service.addCharacteristic(characApp);
Log.i("vbeInit_ASN_Ext_Server","addCharApp retruned: "+ret);
ret = service.addCharacteristic(characMsg);
Log.i("vbeInit_ASN_Ext_Server","addCharMsg retruned: "+ret);

ret = mGattServer.addService(service);
Log.i("vbeInit_ASN_Ext_Server","addService retruned: "+ret);

Any idea what might be the problem? I noticed that there is function
. I'm not sure how to use it. I'm using standard
. But I guess if I would do something wrong it shall work never - not sometimes...
I'm using Android M (6.0.1) on Samsung SM-G920F.


I noticed that after phone restart it always works. After application close and reopen it usually does not works. It does not works in different ways ->

  • sometimes no characteristic is found;

  • sometimes only first characteristic is found

  • sometimes only last(second) characteristic is found.

When I start Gatt Server I do it like this:

mGattServer = bluetoothManager.openGattServer(appContext, mGattServerCallback);

When I close app (
) I do close gattserver:


I also tried not to close the GATT server, but it did not help. Any ideas what might get wrong between closing and reopening?


So I may have found the reason. I'm adding 2 services: ANS and my service ANS_extension. It seems it helps when I wait after adding the service on call back onServiceAdded()

So now it looks like this:

public static UUID UUID_SupportedNewAlertCategory     = UUID.fromString("00002a47-0000-1000-8000-00805f9b34fb");
public static UUID UUID_NewAlert                      = UUID.fromString("00002a46-0000-1000-8000-00805f9b34fb");
// descriptor used for enabling notify feature
public static UUID UUID_Descr_new                     = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
mGattServer = bluetoothManager.openGattServer(appContext, mGattServerCallback);
waitServiceAdded = true;
BluetoothGattService service = new BluetoothGattService(Vbe_Ans.UUID_SERVICE,

BluetoothGattCharacteristic characSupportedNewAlerCategory =
                new BluetoothGattCharacteristic(Vbe_Ans.UUID_SupportedNewAlertCategory,
                        BluetoothGattCharacteristic.PROPERTY_READ ,
BluetoothGattCharacteristic characNewAlert =
                new BluetoothGattCharacteristic(Vbe_Ans.UUID_NewAlert,
                        BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY,
                        BluetoothGattCharacteristic.PERMISSION_READ );
BluetoothGattDescriptor bgd = new BluetoothGattDescriptor(UUID_Descr_new,
                BluetoothGattDescriptor.PERMISSION_READ | BluetoothGattDescriptor.PERMISSION_WRITE);

ret = service.addCharacteristic(characSupportedNewAlerCategory);
ret = service.addCharacteristic(characNewAlert);
ret = mGattServer.addService(service);

waitServiceAdded = true;
//init second service similar way as previous

Then I clear waiting flag waitServiceAdded in GATT server call back. (I'm java newbie so you might want to use some thread mutex synchro to access boolean?)

private BluetoothGattServerCallback mGattServerCallback = new BluetoothGattServerCallback() {
  public void onServiceAdded (int status,
                                    BluetoothGattService service){
    waitServiceAdded = false;