简体   繁体   中英

BLE Android write characteristic data

I am working on a BLE project using Android. I want to write characteristic data and send it to a BLE chip.

Android屏幕截图

I want to rewrite ISEN_Toulon

I used this code to write characteristic data, but data "ISEN_Toulon" isn't replaced by "TEST" as expected.

private BluetoothGattCharacteristic mWriteCharacteristic;

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();
.....
                    // READ
                    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);
                        Log.d("myTag", "1");
                    }
                    // NOTIFY
                    if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                        mNotifyCharacteristic = characteristic;
                        mBluetoothLeService.setCharacteristicNotification(
                                characteristic, true);
                        Log.d("myTag", "2");
                    }

                    // WRITE  
                    characteristic.setWriteType(BluetoothGattCharacteristic.PROPERTY_WRITE);
                    characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
                    characteristic.setWriteType(BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE);

                    mWriteCharacteristic = characteristic;

                    String str = "TEST";
                    byte[] strBytes = str.getBytes();
                    characteristic.setValue(strBytes);
                    writeCharacteristic(characteristic)

                    return true;
                }
                return false;
            }
};

I have encountered the same problem with you. The detail way to solve the problem I do not remember. But I have a code to write BLE characteristics to BLE devices like this:(at least it works for me)

    public OnClickListener clickListener = new OnClickListener() {

    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub
        if (mGattCharacteristics != null) {
            if(charas.size()>=6){
                BluetoothGattCharacteristic characteristic =
                        charas.get(0);
                BluetoothGattCharacteristic characteristic_write = charas.get(5);
                int charaProp_write = characteristic_write.getProperties();
                int charaProp = characteristic.getProperties();
                //String getUUID = characteristic.getUuid().toString();
                if (((charaProp_write | BluetoothGattCharacteristic.PROPERTY_WRITE) > 0)
                        &&  
                        (characteristic_write != null)){

                    if (mNotifyCharacteristic != null) {
                        mBluetoothLeService.setCharacteristicNotification(
                                mNotifyCharacteristic, false);
                        mNotifyCharacteristic = null;
                    }   
                    byte[] writev = new byte[SIMPLEPROFILE_CHAR6_LEN];
                    Arrays.fill(writev, (byte)'0');
                    byte[] getedit1 = edit1.getText().toString().getBytes();//edit1.getText().toString().getBytes();
                    byte[] getedit2 = edit2.getText().toString().getBytes();
                    byte[] getedit3 = edit3.getText().toString().getBytes();


                    //System.out.println(getedit1 + " " + getedit2 + " " + getedit3);

                    if ((getedit1.length + getedit2.length + getedit3.length) <= (max_syvlength+max_spvlength+max_tuvlength)) {
                        //this 'if' can be canceled
                        writev[0] = (byte)'1';
                        writev[1] = (byte)(getedit1.length);
                        writev[2] = (byte)(getedit2.length);
                        writev[3] = (byte)(getedit3.length);
                        System.arraycopy(getedit1, 0, writev, 4, getedit1.length);
                        System.arraycopy(getedit2, 0, writev, 4 + getedit1.length, getedit2.length);
                        System.arraycopy(getedit3, 0, writev, 4 + getedit1.length + getedit2.length, getedit3.length);
                        writev[4 + getedit1.length + getedit2.length + getedit3.length] = '@';
                    }

                    /*
                    for(int i = 0;i<15;i++){
                        Log.d(TAG, "is:" + writev[i]);
                    }
                    */                      

                    characteristic_write.setValue(writev);
                    characteristic_write.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
                    mBluetoothLeService.writeCharacteristic(characteristic_write);

                }
                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);

                }       
                if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                    mNotifyCharacteristic = characteristic;
                    mBluetoothLeService.setCharacteristicNotification(
                            characteristic, true);
                }

            }
        }

        GotoMyActivity();

    }
};

Trying to override callback function in

BluetoothGattCallback mGattCallback = new BluetoothGattCallback(){
//something callback function like:

@Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
      //do something read/write
}

You need to figure out how BLE callback function work!!! Check this out.

Because BLE write/read can only be done in one time. It's mean that if I read a data from characteristic. I can only do another write/read action after previous one done.

Your case is of writing multiple bytes of data to the characteristic to bluetooth device, which has few rules:

  1. Android can not write parallel data packets to the ble device.
  2. The data should not exceed 20 bytes
  3. You should divide the data to chunks and send to ble device
  4. You should wait for the write callback onCharacteristicWrite() before sending next data packet to be written to the ble device.

I know this is old, but as I had a similar issue today, others might like an answer.

The issue it that you set the WriteType 3 times - effectually overwriting the two first values set. Your code:

...
characteristic.setWriteType(BluetoothGattCharacteristic.PROPERTY_WRITE);
characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
characteristic.setWriteType(BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE);

Two issues:

  • The values starting with PROPERTY_ are not write types, hence only WRITE_TYPE_NO_RESPONSE is valid
  • The third call to setWriteType() overwrites the valid value with an invalid value, and the Android stack then ignores your write request.

Unless there is a specific reason to use WRITE_NO_RESPONSE , you should use a normal write ( WRITE_TYPE_DEFAULT ). The Android stack sometimes miss a write - as in the application do call write for example 5 times, but only 1 or 2 of the writes are send over air. This is even when the onCharacteristicWrite() callback reports success.

characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM