This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Addressing Characteristics by Handle with Android

Other Parts Discussed in Thread: CC2541DK-MINI, CC2541

Hello,
I am having severe Problems with the difference in the way BTool and Android access BLE devices.
With BTool I can Read by 16-bit UUID and with the Handle, and wirte data with the Handle.
With Andorid I seem to be able to only write Data using a 128-bit UUID.
Is there any way to address Characteristics, read and write descriptors by their Handle's in Andorid ?

The way I go now is to discover all services, if the UUID matches a Service I want ( using a string compare, UGH! ) I copy the Object and access it from there on. I think this is weird. There should be a more "direct" way to access a Service, i.e. Blindly, without a prior scan of the Device.

I have a KeyFob from the CC2541DK-Mini Kit. I am trying to do everything I do with the BTool, just via Android. I have written code that can get Notified on Keypresses, and I can make the Buzzer beep.
However I seem not to be able to get the accelerometer running.  (It works fine with BTool)

I am trying something like this :

1) Get Services
mBluetoothGatt.discoverServices();

2) Get UUIDs of wanted Characteristics
onServicesDiscovered(BluetoothGatt gatt, int status) {
listOfServices = mBluetoothGatt.getServices();
// iterate over listOfServices
listOfCharacteristics = serviceList_Item.getCharacteristics();
// iterate over listOfCharacteristics
mUuid = characteristicsList_Item.getUuid();
if (mUuid.contains("FFA1")) acc_EN = characteristicsList_Item
if (mUuid.contains("FFA3")) acc_X = characteristicsList_Item
if (mUuid.contains("FFA4")) acc_Y = characteristicsList_Item
if (mUuid.contains("FFA5")) acc_Z = characteristicsList_Item

3) Activate Notifications
mBluetoothGatt.setCharacteristicNotification(acc_EN, true);
mBluetoothGatt.setCharacteristicNotification(acc_X, true);
mBluetoothGatt.setCharacteristicNotification(acc_Y, true);
mBluetoothGatt.setCharacteristicNotification(acc_Z, true);

[Upto here everything works fine, the above calls end with a success (return ture)]

4) Move the Keyfob
Take Keyfob in hand and fiddle with it.

5) Callback
// At this point I would expect that the BluetoothGattCallback is called and onCharacteristicChanged is called.
But nothing happens. Although using the same scheme works fine for the Keypresses on the Keyfob.

The only thing I can think of is that I should NOT call setCharacteristicNotification for the three axes, but instead write a 01:00 to their corresponding settings. But I can't do that, since all of them have the same UUID.
Which makes sense in the context of this post :
http://e2e.ti.com/support/low_power_rf/f/538/t/86482.aspx
Where it is explained that the UUID is the "Type" and the Handle is the "Address". But I cannot access the "Address" from within Android. (Or I am simply doing something incredibly stupid, but can't see it myself.)

I have also looked into BluetoothGattCharacteristic.getInstanceId() from the Andorid API. The explanation says "If a remote device offers multiple characteristics with the same UUID, the instance ID is used to distuinguish between characteristics."
This looked like it could be a fancy way to say "This is the Address". But it always returns zero, no changes ever.

Hope someone can halp me out with this.
This is not specific to the Accellerometer, but in general about Handle's and UUID with Android.


  • Hi Burak Ozhan,

    I am facing similar problem as yours. Were you able to find a solution for it?

    In my case, I am using proximity reporter profile in my application. It has two services having same UUID as shown below:
    Link Loss Service -> "Alert Level" characteristic with UUID 0x2A06
    Immediate Alert Service -> "Alert Level" characteristic with UUID 0x2A06
    I am able to write into the "Alert Level" characteristics of these services independently using Btool (I get handles of these characteristics using "Discover characteristic by UUID" in BTool).
    But through Android App, I am not able to write into these characteristics independently. It is sure that somehow I need to discover Handles of these characteristics.
    Any help in this regards is highly appreciated
  • Hi Vikas,
    No I was not able to find a way to directly address a characteristic. What I do now is, upon connection with a CC2541 I do a complete scan.
    During the scan in

    onServicesDiscovered( gatt, status ) 

    when I see Service UUID 1803, by looking for

    currentBluetoothGattService.getUUID().toString().contains("1803")

    I look up the characteristics for that Service with :

    currentBluetoothGattService.getCharacteristics();

    When I come across a characteristic that contains the "Type-UUID" 0x2A06

    currentBluetoothGattCharacteristic.getUuid()).contains("2a06")

    then I do remember that specific characteristic by putting a global pointer to :

    if (currentBluetoothGattCharacteristic.getUuid()).contains("2a06")){
    	linkloss = currentBluetoothGattCharacteristic;
    }

    So after scanning once the whole device I have access to the linkloss service by calling linkloss from anywhere.

    I hope we agree on the fact that this is the most ugliest solution to this problem, but I could not find any other Workaround.

    Does this info help you?



  • I have exactly the same issue and I have NOT found a solution yet.

    TI documentation talks about handle and BTTool and BLE device monitor uses handles to enable acceleration but Android has no concept of handles.

    Not knowing this issue is posted I have posted this same issue but I have not received a reply.

    Are there TI BLE Android team members reading this forum...please assist. Many people are wasting time on the this issue - which hopefully TI team knows how to resolve.  We are looking for expert comments from TI.

  • A few insights from a fellow Android/Java newbie:

    1. Android does a lot of GATT work 'under the hood'. For example, the first time Android encounters a device, UUID's, handles and properties are cached. Subsequent connections are very quick because Android uses cached information.

    2. The Android BLE developers chose to use UUID as the characteristic identifier in GATT API's; handles are not directly exposed to applications. Internally, Android maps UUID's to handles and uses handles to access characteristics, but apps have no need to know the handle.

    3. A great resource is the free Android (and iOS) sample code available from the BT SIG. Look for the Application Accelerator Kit at https://developer.bluetooth.org/Pages/default.aspx

  • Hi All,

    I'm also facing the same issue, When I try to enable the configuration of Tracker by writing the configuration(01:00) setting using descriptor then I'm always getting false and not able able to setup to read address information.

    Here is my code snippet.

    public boolean EnableAccel(int val) {
    if (mBluetoothGatt != null) {
    BluetoothGattService keyService = mBluetoothGatt.getService(ACCEL_SERVICE_UUID);
    if (keyService == null) {
    System.out.println("key service is null");
    return false;
    } else {
    System.out.println("key service is not null");
    }
    BluetoothGattCharacteristic characteristic =
    keyService.getCharacteristic(ACCEL_ENABLE_UUID);
    if (characteristic == null) {
    System.out.println("ch is null");
    return false;
    }
    byte[] arrayOfByte = new byte[1];
    switch (val) {
    case 1:
    arrayOfByte[0] = (byte) 0x0100;
    break;
    case 2:
    arrayOfByte[0] = (byte) 0x0000;
    break;
    }
    characteristic.setValue(arrayOfByte);
    status = mBluetoothGatt.writeCharacteristic(characteristic);
    //enableNotification(true, characteristic);
    System.out.println("status of enabling" + status);
    if (status) {
    BluetoothGattCharacteristic enableX = keyService.getCharacteristic(X_ENABLE_UUID);
    if (enableX == null) {
    System.out.println("x char not found");
    } else {
    System.out.println("read characteristic");
    // mBluetoothGatt.readCharacteristic(enableX);
    BluetoothGattDescriptor gatDesc = enableX.getDescriptor(X_ENABLE_UUID_DESC);
    if (gatDesc == null) {
    System.out.println("x descriptor not found");
    return false;
    }
    byte[] arrayOfBytee = new byte[2];
    arrayOfBytee[0] = (byte) 0x0001;
    gatDesc.setValue(arrayOfBytee);
    boolean myval = mBluetoothGatt.writeDescriptor(gatDesc);
    System.out.println("return value is" + myval);
    mBluetoothGatt.setCharacteristicNotification(enableX, true);
    //setDescriptorNotification(gatDesc,true,enableX);
    }
    }
    }
    return status;
    }

    I used the BTools app and able to enable the tracker using that B tools app. I'm really facing alot of issues due to this error. Any help will really appreciated.

    Thanks in advance.