Search code examples
javaandroidbluetooth-lowenergygattbluetooth-gatt

In BLE android app onCharacteristicRead is not calling even i have write bluetoothGatt.readCharacteristic(gattCharacteristic)


I'm developing an app to connect with BLE device and I'm following google developer guides.

As per developer guide I have scanned BLE device and successfully establish connection with them and able to get available services and characteristics.

Here my problem comes when I'm trying to read characteristic value using

bluetoothGatt.readCharacteristic(gattCharacteristic)

but it is not working it is not calling the gatt callback method

onCharacteristicRead

Those characteristic property is READ because of that I'm not using Descriptor or any notification enabled.

I have try all solutions mentioned in SO and Google but still I'm unable to resolve this problem

I'm new to this concept if any one can help me.

Please find following code for reference:

This class is for service of bluetoothgatt callback.

private BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            String intentAction;
            bluetoothGatt = gatt;
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                //bluetoothGatt = gatt;
                intentAction = Constants.GATT_CONNECTED;
                Log.i(TAG, "Connected to GATT server.");
                // Attempts to discover services after successful connection.
                Log.i(TAG, "Attempting to start service discovery:" +
                        bluetoothGatt.discoverServices());
                gatt.discoverServices();
                broadCastUpdates(intentAction);
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                intentAction = Constants.GATT_DISCONNECTED;
                Log.i(TAG, "Disconnected to GATT server.");
                broadCastUpdates(intentAction);
            }
            super.onConnectionStateChange(gatt, status, newState);
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                broadCastUpdates(Constants.GATT_SERVICE_DISCOVERED);
                Log.i("Services count", " " + gatt.getServices().size());
            } else {
                Log.w(TAG, "onServicesDiscovered received: " + status);
            }
            super.onServicesDiscovered(gatt, status);
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.e(TAG, "Characteristics calling");
                UUID charUuid = characteristic.getUuid();
                Intent intent = new Intent(Constants.GATT_DATA_AVAILABLE);
                Bundle bundle = new Bundle();
                // Putting the byte value read for GATT Db
                bundle.putByteArray(Constants.EXTRA_BYTE_VALUE,
                        characteristic.getValue());
                bundle.putString(Constants.EXTRA_BYTE_UUID_VALUE,
                        characteristic.getUuid().toString());
                if (charUuid
                        .equals(UUID_MANUFATURE_NAME_STRING)) {
                    bundle.putString(Constants.EXTRA_MNS_VALUE,
                            Constants.getDisplayString(characteristic));
                }
                // Model number read value
                else if (charUuid.equals(UUID_MODEL_NUMBER_STRING)) {
                    bundle.putString(Constants.EXTRA_MONS_VALUE,
                            Constants.getDisplayString(characteristic));
                }
                // Serial number read value
                else if (charUuid
                        .equals(UUID_SERIAL_NUMBER_STRING)) {
                    bundle.putString(Constants.EXTRA_SNS_VALUE,
                            Constants.getDisplayString(characteristic));
                }
                // Hardware revision read value
                else if (charUuid
                        .equals(UUID_HARDWARE_REVISION_STRING)) {
                    bundle.putString(Constants.EXTRA_HRS_VALUE,
                            Constants.getDisplayString(characteristic));
                }
                // Firmware revision read value
                else if (charUuid
                        .equals(UUID_FIRWARE_REVISION_STRING)) {
                    bundle.putString(Constants.EXTRA_FRS_VALUE,
                            Constants.getDisplayString(characteristic));
                }
                // Software revision read value
                else if (charUuid
                        .equals(UUID_SOFTWARE_REVISION_STRING)) {
                    bundle.putString(Constants.EXTRA_SRS_VALUE,
                            Constants.getDisplayString(characteristic));
                }
                // PNP ID read value
                else if (charUuid.equals(UUID_PNP_ID)) {
                    bundle.putString(Constants.EXTRA_PNP_VALUE,
                            Constants.getDisplayString(characteristic));
                }
                // System ID read value
                else if (charUuid.equals(UUID_SYSTEM_ID)) {
                    bundle.putString(Constants.EXTRA_SID_VALUE,
                            Constants.getDisplayString(characteristic));
                }
                intent.putExtras(bundle);
                sendBroadcast(intent);
            }
            Log.e(TAG, "Characterstics calling");
            //broadCastUpdates(Constants.GATT_DATA_AVAILABLE, characteristic);
            //super.onCharacteristicRead(gatt, characteristic, status);
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            Log.e(TAG, "Characteristic write calling");
            super.onCharacteristicWrite(gatt, characteristic, status);
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            Log.e(TAG, "Characteristic change calling");
            super.onCharacteristicChanged(gatt, characteristic);
        }

        @Override
        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            Log.e(TAG, "Descriptor calling");
            super.onDescriptorRead(gatt, descriptor, status);
        }

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            Log.e(TAG, "Descriptor write calling");
            super.onDescriptorWrite(gatt, descriptor, status);
        }

        @Override
        public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
            super.onReliableWriteCompleted(gatt, status);
        }

        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
            super.onReadRemoteRssi(gatt, rssi, status);
        }
    };

   /* public static void setNotifyCharacteristics(BluetoothGattCharacteristic notifyCharacteristics) {
        bluetoothGatt.setCharacteristicNotification(notifyCharacteristics, true);
        BluetoothGattDescriptor gattDescriptor = notifyCharacteristics.getDescriptor(notifyCharacteristics.getDescriptors().get(0).getUuid());
        gattDescriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        bluetoothGatt.writeDescriptor(gattDescriptor);
    }*/

    public void readCharacteristics(BluetoothGattCharacteristic gattCharacteristic) {
        if (bluetoothGatt != null) {
            int charaProp = gattCharacteristic.getProperties();
            Log.e(TAG, "Property-" + charaProp);
            Log.e(TAG, gattCharacteristic.getUuid().toString());
            bluetoothGatt.discoverServices();
            bluetoothGatt.readCharacteristic(gattCharacteristic);
            Log.e(TAG, "Gatt is not null");
        } else {
            Log.e(TAG, "Gatt is null");
        }
    }

Below class is where i'm calling readCharacteristic

 private BroadcastReceiver characteristicReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        Bundle extras = intent.getExtras();
        if (Constants.GATT_DATA_AVAILABLE.equals(action)) {
            if (extras != null) {
                String name = extras.getString(Constants.EXTRA_MNS_VALUE);
                Log.e("This is test name :-", name);
                byte[] valueArry = extras.getByteArray(Constants.EXTRA_BYTE_VALUE);
                displayHexValue(valueArry);
                displayName(tvTempType.getText().toString());
            }
        } else {
            Toast.makeText(context, "There is no extra data.", Toast.LENGTH_SHORT).show();
        }
    }
};

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_character_details);

    try {
        tvUid = findViewById(R.id.tvCharUid);
        tvTemprature = findViewById(R.id.tvTemprature);
        tvCharName = findViewById(R.id.tvCharName);
        tvTempType = findViewById(R.id.tvTypename);

        ArrayList<BluetoothGattCharacteristic> bluetoothGattCharacteristics = getIntent().getParcelableArrayListExtra(Constants.CHARACTERISTIC);
        int selectPos = getIntent().getIntExtra(Constants.SELECTED_SERVICE, 0);
        gattCharacteristic = bluetoothGattCharacteristics.get(selectPos);
        registerReceiver(characteristicReceiver, Constants.makeGattUpdateIntentFilter());
        BLEGattService bleGattService = new BLEGattService();
        bleGattService.readCharacteristics(gattCharacteristic);
        String uid = gattCharacteristic.getUuid().toString();
        String displayUid = Constants.getDisplayString(gattCharacteristic);
        tvUid.setText(displayUid);
    } catch (Exception e) {
        e.printStackTrace();
    }
    /*String name = Constants.getDisplayString(gattCharacteristic);
    tvCharName.setText(name);*/

}

@Override
protected void onResume() {
    super.onResume();
    registerReceiver(characteristicReceiver, Constants.makeGattUpdateIntentFilter());
}

@Override
protected void onDestroy() {
    super.onDestroy();
    unregisterReceiver(characteristicReceiver);
}

Solution

  • Try to use your own custom method for each characteristics. You need to know UUID of your service and UUID of your characteristic:

    public void readCustomCharacteristic() {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        }
        /*check if the service is available on the device*/
        BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("UUID of service"));
        if(mCustomService == null){
            Log.w(TAG, "Custom BLE Service not found");
            return;
        }
        /*get the read characteristic from the service*/
        BluetoothGattCharacteristic mReadCharacteristic = mCustomService.getCharacteristic(UUID.fromString("UUID of characteristic"));
        if(mBluetoothGatt.readCharacteristic(mReadCharacteristic) == false){
            Log.w(TAG, "Failed to read characteristic");
        }
    }
    
    public void writeCustomCharacteristic(byte[] value) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        }
        /*check if the service is available on the device*/
        BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("UUID of service"));
        if(mCustomService == null){
            Log.w(TAG, "Custom BLE Service not found");
            return;
        }
        /*get the read characteristic from the service*/
        BluetoothGattCharacteristic mWriteCharacteristic = mCustomService.getCharacteristic(UUID.fromString("UUID of characteristic"));
        mWriteCharacteristic.setValue(value);
        if(mBluetoothGatt.writeCharacteristic(mWriteCharacteristic) == false){
            Log.w(TAG, "Failed to write characteristic");
        }
    }