21

I am working on a BLE project (Android application) using Android 4.3 API, i have used sample BLE app it is only reading characteristics in DeviceControlActivity.activity, but i want to write characteristics and send it to BLE chip on clicking a button. How can I write data on chip cc2540 .. Basically i don't know the step by step procedure to write characteristics.

write i can only see the name and id of device with following piece of code in DeviceControlActivity

 private final ExpandableListView.OnChildClickListener servicesListClickListner =
        new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
                                        int childPosition, long id) {
                if (mGattCharacteristics != null) {
                    final BluetoothGattCharacteristic characteristic =
                            mGattCharacteristics.get(groupPosition).get(childPosition);
                    final int charaProp = characteristic.getProperties();
                    if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
                        // If there is an active notification on a characteristic, clear
                        // it first so it doesn't update the data field on the user interface.
                        if (mNotifyCharacteristic != null) {
                            mBluetoothLeService.setCharacteristicNotification(
                                    mNotifyCharacteristic, false);
                            mNotifyCharacteristic = null;
                        }
                        mBluetoothLeService.readCharacteristic(characteristic);
                        showDialog("reading");
                    }

                    if ((charaProp | BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
                        // If there is an active notification on a characteristic, clear
                        // it first so it doesn't update the data field on the user interface.
                        if (mNotifyCharacteristic != null) {
                            mBluetoothLeService.setCharacteristicNotification(
                                    mNotifyCharacteristic, false);
                            mNotifyCharacteristic = null;
                        }
                        mBluetoothLeService.writeCharacteristic(characteristic);
                        showDialog("writing");
                        //characteristic.setValue(bytes);
                        //characteristic.setValue("testing");
                        //characteristic.setWriteType(BluetoothGattCharacteristic.PERMISSION_WRITE);
                    }
                    if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                        mNotifyCharacteristic = characteristic;
                        mBluetoothLeService.setCharacteristicNotification(
                                characteristic, true);
                    }

                    byte[] value = {0x00, (byte) (0xB9) , 0x0D, (byte) (0x90), 0x2F};
                    if(!characteristic.setValue(value)) 
                    {
                        Log.w(TAG, "Couldn't set characteristic's local value"); 
                        //return;
                    }

                    characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
                    /*if(!writeCharacteristic.writeCharacteristic(characteristic))
                    { 
                        Log.w(TAG, "Couldn't write characteristic");
                    }*/

                    return true;
                }
                return false;
            }
};
ThomasW
  • 16,079
  • 4
  • 73
  • 101
Nomiluks
  • 1,783
  • 5
  • 24
  • 49

4 Answers4

47

The following code is write characteristic using byte[] data:

    public boolean writeCharacteristic(){

    //check mBluetoothGatt is available
    if (mBluetoothGatt == null) {
        Log.e(TAG, "lost connection");
        return false;
    }
    BluetoothGattService Service = mBluetoothGatt.getService(your Services);
    if (Service == null) {
        Log.e(TAG, "service not found!");
        return false;
    }
    BluetoothGattCharacteristic charac = Service
            .getCharacteristic(your characteristic);
    if (charac == null) {
        Log.e(TAG, "char not found!");
        return false;
    }

    byte[] value = new byte[1];
    value[0] = (byte) (21 & 0xFF);
    charac.setValue(value);
    boolean status = mBluetoothGatt.writeCharacteristic(charac);
    return status;
}
Huy Tower
  • 7,162
  • 13
  • 49
  • 81
Nam Pham
  • 854
  • 10
  • 11
  • thank you @Nam Pham kindly explain why you are doing this 21&0xFF ? – Nomiluks Dec 02 '13 at 09:02
  • 1
    21 & 0xFF. it's just data which I want to write to BLE device. So, you should replace it by your data. Max data length you can write which is 20 bytes. If you have data length > 20 bytes, you need to fragment data into 20 byte trunk and write – Nam Pham Dec 05 '13 at 07:42
  • thanks but i am asking about and "&" that you are using in your code why you are using "& 0xFF" before writing.. – Nomiluks Dec 06 '13 at 06:52
  • 1
    @Nomi: it's just my habbit. you can use "value[0] = (byte) 21;" . It's same result – Nam Pham Dec 18 '13 at 07:19
  • Which Service to pass on place of "your Services"? – Shreyash Mahajan Feb 08 '14 at 14:03
  • "your Services" is basically the UUID of the service. in my case it is MY_SERIVCE_CONTROLLER = "0000fff0-0000-1000-8000-00805f9b34fb" – Nomiluks Apr 30 '14 at 07:57
  • writeCharcteristics getting failed every time – Prasad Jul 24 '16 at 14:58
  • Sir, I have a problem with this problem " Log.e(TAG, "char not found!");" sir please guide me. Thank you so much, sir. – chetan mahajan Nov 02 '19 at 13:56
  • 1
    @chetanmahajan, Please check the service and character UUID which you want to write data. You can check them by using the LightBlue app. please ensure that service UUID is existing on your device and character UUID belongs to it – Nam Pham Nov 04 '19 at 07:49
  • How do you get a reference to mBluetoothGatt as the question asked doesn't have a reference to it since the connectGatt() is called from the BluetoothLeService and not from the DeviceControlActivity. @Nomiluks Did you implement a public method in the Bluetooth service rather than the devicecontrolactivity? – Goku Nov 28 '20 at 20:01
8

Please note that the logic OR in:
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0)" in the original post should be a logic AND for the permission check to work. Same for the second charaProp comparison. Otherwise bot statements are true regardless of the actual permission flag.

Michael Yaworski
  • 12,398
  • 17
  • 59
  • 91
Miguel
  • 81
  • 2
6

The following code is write characteristic using string data in utf-8 format:

public void writeCharacteristic(BluetoothGattCharacteristic characteristic,
            String data) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        }

        Log.i(TAG, "characteristic " + characteristic.toString());
        try {
            Log.i(TAG, "data " + URLEncoder.encode(data, "utf-8"));

            characteristic.setValue(URLEncoder.encode(data, "utf-8"));

            // TODO
            mBluetoothGatt.writeCharacteristic(characteristic);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

Hope it helps!

Huy Tower
  • 7,162
  • 13
  • 49
  • 81
0
public boolean writeCharacteristic(byte value[],int type){
    //check mBluetoothGatt is available
    if (mBluetoothGatt == null) {
        Log.e(TAG, "lost connection");
        return false;
    }
    BluetoothGattService Service = mBluetoothGatt.getService(UUID_SIMPLESERVICE);
    if (Service == null) {
        Log.e(TAG, "service not found!");
        //////////NO service found...........
         return false;
    }
    BluetoothGattCharacteristic charac1 = null;
    boolean status1 = false;

    if(type==1) {
        charac1 = Service.getCharacteristic(UUID_PORT1);
        charac1.setValue(value);
        status1 = mBluetoothGatt.writeCharacteristic(charac1);
        Log.v("________BLESERVICE____", "___WRITE CHARATERISTICS STATUS:_________"+status1);
        onReliableWriteCompleted(status1);
    }
    if (charac1 == null) {
        Log.e(TAG, "char not found!");
        return false;
    }

    Log.v("___TYPE___","______________________"+type);
    return status1;
}
Pang
  • 8,605
  • 144
  • 77
  • 113
image
  • 49
  • 1
  • 13
  • hi please check this link it is a urgent task for me http://stackoverflow.com/questions/23076353/how-to-update-the-battery-level-for-every-5seconds-in-ble-in-android – image Apr 15 '14 at 08:14