1

I'm using two BLE peripheral sensors and 1 mobile phone (central). Each BLE peripheral device works well (tested individually).

I followed the <BluetoothLeGatt> example. My phone is HUAWEI Mate 10, which uses Android version 10 and supports BLE 4.2.

In my Android BLE App, after press the Connect Button on the 1st page, App will automatically connect to 2 BLE devices with the names "BC805M BLE ADC1" and "BC805M BLE ADC2".

It seems the App could connect with 2 BLE devices successfully. However, no data received (fail to subscribe characteristic notification). BluetoothGattCallback.onCharacteristicChanged() method is never fired. Therefore, the action never becomes "ACTION_DATA_AVAILABLE".

BLE App screenshot 1

BLE App screenshot 2

I understand the BLE communication is serial. Some people suggested using "onDescriptorWrite()" in BluetoothGattCallback(). However, I don't fully understand how to do it. I attached my Android Studio project here. It would be very appreciated if someone could find the issue.

public class DeviceControlActivity extends Activity {
private final static String TAG = DeviceControlActivity.class.getSimpleName();
public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
public static final String NUMBER_OF_DEVICE = "NUMBER OF DEVICE";
public static final String EXTRAS_DEVICE_NAME_1 = "DEVICE_NAME1";
public static final String EXTRAS_DEVICE_ADDRESS_1 = "DEVICE_ADDRESS1";
public static final String NUMBER_OF_DEVICE_1 = "NUMBER OF DEVICE1";

private TextView mConnectionState;
private TextView mDataField;
private TextView mThumb;
private TextView mIndex;
private TextView mThumb1;
private TextView mIndex1;

private String mDeviceName;
private String mDeviceAddress;
private String mDeviceName1;
private String mDeviceAddress1;

private int DEVICE_NUMBER;
private int DEVICE_NUMBER1;
private int TOTAL_DEVICE;

private BluetoothLeService mBluetoothLeService;

private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics =
        new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics1 =
        new ArrayList<ArrayList<BluetoothGattCharacteristic>>();

private boolean mConnected = false;
private BluetoothGattCharacteristic mNotifyCharacteristic;
private BluetoothGattCharacteristic mNotifyCharacteristic1;

private final String ServiceUUID = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";     
private final String CharUUID    = "6e400003-b5a3-f393-e0a9-e50e24dcca9e";      
private final String LIST_NAME   = "NAME";
private final String LIST_UUID   = "UUID";


// Code to manage Service lifecycle.
private final ServiceConnection mServiceConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName componentName, IBinder service) {
        Log.d(TAG,"Service Connected Called");
        mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
        if (!mBluetoothLeService.initialize()) {
            finish();
        }
        mBluetoothLeService.connect(mDeviceAddress,0);
        mBluetoothLeService.connect(mDeviceAddress1, 1);
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        Log.d(TAG,"Service DISConnected Called");
        mBluetoothLeService = null;
    }
};


private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
            mConnected = true;
            updateConnectionState(R.string.connected);
            invalidateOptionsMenu();
            Log.e(TAG,"ACTION_GATT_CONNECTED ");
        } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
            Log.e(TAG,"WHEN IS ACTION GATT DISCONNECTED");
            mConnected = false;
            updateConnectionState(R.string.disconnected);
            invalidateOptionsMenu();
            Log.e(TAG,"ACTION_GATT_DISCONNECTED ");
            clearUI();
        } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
            Log.e(TAG,"ACTION_GATT_SERVICE_DISCOVERED ");
            updateGattServices(mBluetoothLeService.getSupportedGattServices(0),0);
            try {
                Thread.sleep(700);
            }catch(InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
            Log.e(TAG,"getSupportedGattServices() is done for device #0");
            updateGattServices(mBluetoothLeService.getSupportedGattServices(1), 1);
            try {
                Thread.sleep(700);
            }catch(InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
            Log.e(TAG,"getSupportedGattServices() is done for device #1");
            updateDATA();
        } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
            Log.d(TAG,"ACTION_DATA_AVAILABLE ");
            mBluetoothLeService.readCharacteristic(mNotifyCharacteristic,0);
            displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA),0);
            mBluetoothLeService.readCharacteristic(mNotifyCharacteristic1, 1);
            displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA1), 1);
        }
    }
};

private final boolean updateDATA(){
    int servicePos = 0;
    int charPos = 0;

    if(mGattCharacteristics!=null&&mGattCharacteristics.size()!=0){
        final BluetoothGattCharacteristic characteristic = mGattCharacteristics.get(servicePos).get(charPos);
        final int charPro = characteristic.getProperties();
        if((charPro|BluetoothGattCharacteristic.PROPERTY_READ)>0){
            if(mNotifyCharacteristic!= null){
                mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic,false,0);
            }
        }
        mBluetoothLeService.readCharacteristic(characteristic,0);
        if ((charPro | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
            Log.d(TAG, "PROPER_NOTIFY > 0");
            Log.d(TAG, " ");
        }
        return true;
    }
    return false;
}

private void clearUI() {
    mDataField.setText(R.string.no_data);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    Log.e(TAG,"2.2 onCreate() starts! ");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.gatt_services_characteristics);

    final Intent intent = getIntent();
    mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);
    mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);
    mDeviceName1 = intent.getStringExtra(EXTRAS_DEVICE_NAME_1);
    mDeviceAddress1=intent.getStringExtra(EXTRAS_DEVICE_ADDRESS_1);
    DEVICE_NUMBER=intent.getIntExtra(NUMBER_OF_DEVICE,0);
    DEVICE_NUMBER1=intent.getIntExtra(NUMBER_OF_DEVICE_1,0);


    ((TextView) findViewById(R.id.device_address)).setText(mDeviceAddress+" AND "+mDeviceAddress1);
    mConnectionState = (TextView) findViewById(R.id.connection_state);
    mDataField = (TextView) findViewById(R.id.data_value);
    mThumb = (TextView) findViewById(R.id.Thumb);
    mIndex = (TextView) findViewById(R.id.Index);
    mThumb1 = (TextView) findViewById(R.id.Thumb1);
    mIndex1 = (TextView) findViewById(R.id.Index1);

    Log.d(TAG,"MY DEVICE NAME "+mDeviceName);
    Log.d(TAG,"MY DEVICE ADDRESS "+mDeviceAddress);
    Log.d(TAG,"MY DEVICE NUMBER "+DEVICE_NUMBER);
    Log.d(TAG,"MY DEVICE NAME1 "+mDeviceName1);
    Log.d(TAG,"MY DEVICE ADDRESS1 "+mDeviceAddress1);
    Log.d(TAG,"MY DEVICE NUMBER1 "+DEVICE_NUMBER1);
    getActionBar().setTitle(mDeviceName+" "+mDeviceName1);
    getActionBar().setDisplayHomeAsUpEnabled(true);
    Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
    bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
}

@Override
protected void onResume() {
    Log.e(TAG,"2.2 onResume is Called");
    super.onResume();
    registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
    if (mBluetoothLeService != null) {
        boolean result = mBluetoothLeService.connect(mDeviceAddress,0);
        boolean result1 = mBluetoothLeService.connect(mDeviceAddress1, 1);
        Log.d(TAG, "Connect request result = " + result+" "+result1);
    }
}

@Override
protected void onPause() {
    Log.d(TAG,"onPause is called");
    super.onPause();
    unregisterReceiver(mGattUpdateReceiver);
}

@Override
protected void onDestroy() {
    Log.d(TAG,"onDestroy is Called");
    super.onDestroy();
    unbindService(mServiceConnection);
    mBluetoothLeService = null;
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.gatt_services, menu);
    if (mConnected) {
        menu.findItem(R.id.menu_connect).setVisible(false);
        menu.findItem(R.id.menu_disconnect).setVisible(true);
    } else {
        menu.findItem(R.id.menu_connect).setVisible(true);
        menu.findItem(R.id.menu_disconnect).setVisible(false);
    }
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch(item.getItemId()) {
        case R.id.menu_connect:
            mBluetoothLeService.connect(mDeviceAddress,0);
            mBluetoothLeService.connect(mDeviceAddress1, 1);
            return true;
        case R.id.menu_disconnect:
            Log.d(TAG,"FIRST DEVICE"+DEVICE_NUMBER);
            mBluetoothLeService.disconnect();
            return true;
        case android.R.id.home:
            Log.d(TAG,"HOME IS PRESSED");
            onBackPressed();
            return true;
    }
    return super.onOptionsItemSelected(item);
}

private void updateConnectionState(final int resourceId) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mConnectionState.setText(resourceId);
        }
    });
}

private void displayData(String data,int device) {
    if (data != null && device ==0) {
        mThumb1.setText(data.substring(1, 4));
        mIndex1.setText(data.substring(5, 8));
    }
    else if(data != null && device == 1) {
        mThumb.setText(data.substring(1, 4));
        mIndex.setText(data.substring(5, 8));
    }
}

private void updateGattServices(List<BluetoothGattService> gattServices,int device) {
    if (gattServices == null) return;
    String uuid = null;
    String unknownServiceString = getResources().getString(R.string.unknown_service);
    String unknownCharaString = getResources().getString(R.string.unknown_characteristic);
    ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();

    if(device ==0) {
        mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
        Log.e(TAG,"mGattCharacteristics is created for device #0");
    }
    else if(device ==1) {
        mGattCharacteristics1 = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
        Log.e(TAG,"mGattCharacteristics is created for device #1");
    }

    int i=0;
    int j=0;
    // Loops through available GATT Services.
    Log.e(TAG,"Start For Loop");
    for (BluetoothGattService gattService : gattServices) {
        Log.e(TAG,"Service index = " + i);
        HashMap<String, String> currentServiceData = new HashMap<String, String>();
        uuid = gattService.getUuid().toString();
        if(uuid.equals(ServiceUUID)) {
            Log.e(TAG,"Selected Service index = " + i);
            currentServiceData.put(LIST_NAME, SampleGattAttributes.lookup(uuid, unknownServiceString));
            currentServiceData.put(LIST_UUID, "");
            gattServiceData.add(currentServiceData);
            ArrayList<HashMap<String, String>> gattCharacteristicGroupData = new ArrayList<HashMap<String, String>>();
            List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
            ArrayList<BluetoothGattCharacteristic> charas = new ArrayList<BluetoothGattCharacteristic>();

            // Loops through available Characteristics.
            for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                Log.e(TAG,"Characteristic index = " + j);
                charas.add(gattCharacteristic);
                HashMap<String, String> currentCharaData = new HashMap<String, String>();
                uuid = gattCharacteristic.getUuid().toString();
                if(uuid.equals(CharUUID)) {
                    Log.e(TAG,"Selected Characteristic index = " + j);
                    currentCharaData.put(
                            LIST_NAME, SampleGattAttributes.lookup(uuid, unknownCharaString));
                    currentCharaData.put(LIST_UUID, "");
                    gattCharacteristicGroupData.add(currentCharaData);
                    if(device ==0){
                        mNotifyCharacteristic=gattCharacteristic;
                    }
                    else if(device ==1){
                        mNotifyCharacteristic1=gattCharacteristic;
                    }
                }
                j = j +1;
            }
            if(device ==0){
                mGattCharacteristics.add(charas);
            }
            else if(device ==1){
                mGattCharacteristics1.add(charas);
            }
        }
        i = i + 1 ;
    }

}

private static IntentFilter makeGattUpdateIntentFilter() {
    final IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
    intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
    intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
    intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
    return intentFilter;
}

}

public class BluetoothLeService extends Service {
private final static String TAG = BluetoothLeService.class.getSimpleName();

private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private String mBluetoothDeviceAddress;
private String mBluetoothDeviceAddress1;
private BluetoothGatt mBluetoothGatt;
private BluetoothGatt mBluetoothGatt1;
private int mConnectionState = STATE_DISCONNECTED;

private static final int STATE_DISCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;

public final static String ACTION_GATT_CONNECTED =
        "com.example.bluetooth.le.ACTION_GATT_CONNECTED";
public final static String ACTION_GATT_DISCONNECTED =
        "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
public final static String ACTION_GATT_SERVICES_DISCOVERED =
        "com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_DATA_AVAILABLE =
        "com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
public final static String EXTRA_DATA =
        "com.example.bluetooth.le.EXTRA_DATA";
public final static String EXTRA_DATA1 =
        "com.example.bluetooth.le.EXTRA_DATA1";

public final static UUID ServiceUUID2 = UUID.fromString("6e400001-b5a3-f393-e0a9-e50e24dcca9e");
public final static UUID CharUUID2    = UUID.fromString("6e400003-b5a3-f393-e0a9-e50e24dcca9e");

// Implements callback methods for GATT events that the app cares about.  For example,
// connection change and services discovered.
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        String intentAction;
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            intentAction = ACTION_GATT_CONNECTED;
            mConnectionState = STATE_CONNECTED;
            broadcastUpdate(intentAction);
            Log.e(TAG, "Connected to GATT server.");
            // Attempts to discover services after successful connection.
            Log.e(TAG, "Attempting to start service discovery:" + mBluetoothGatt.discoverServices());

        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            intentAction = ACTION_GATT_DISCONNECTED;
            mConnectionState = STATE_DISCONNECTED;
            Log.e(TAG, "Disconnected from GATT server.");
            broadcastUpdate(intentAction);
        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
            broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
        } else {
            Log.e(TAG, "onServicesDiscovered received: " + status);
        }
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt,
                                     BluetoothGattCharacteristic characteristic,
                                     int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic,0);
        }
        Log.e(TAG,"onCHAR READ");
    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,
                                        BluetoothGattCharacteristic characteristic) {
        broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic,0);
        Log.e(TAG,"onCharacteristicChanged #0 = ACTION_DATA_AVAILABLE, Done! ");
    }

    @Override
    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
        super.onDescriptorWrite(gatt, descriptor, status);
        Log.e(TAG,"onDescriptorWrite #0, Done! ");
    }


};

private final BluetoothGattCallback mGattCallback1 = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        String intentAction;
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            intentAction = ACTION_GATT_CONNECTED;
            mConnectionState = STATE_CONNECTED;
            broadcastUpdate(intentAction);
            Log.e(TAG, "Connected to GATT server.");
            Log.e(TAG, "Attempting to start service discovery:" +
                    mBluetoothGatt1.discoverServices());
        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            intentAction = ACTION_GATT_DISCONNECTED;
            mConnectionState = STATE_DISCONNECTED;
            Log.e(TAG, "Disconnected from GATT server.");
            broadcastUpdate(intentAction);
        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
            broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
        } else {
            Log.e(TAG, "onServicesDiscovered received: " + status);
        }
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt,
                                     BluetoothGattCharacteristic characteristic,
                                     int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic,1);
        }
        Log.e(TAG,"onCHAR READ in callback 1");
    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,
                                        BluetoothGattCharacteristic characteristic) {
        broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic,1);
        Log.e(TAG,"onCharacteristicChanged #0 = ACTION_DATA_AVAILABLE, Done! ");
    }

    @Override
    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
        Log.e(TAG,"onDescriptorWrite starts");
        if (descriptor.getUuid().equals(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG)) {
            BluetoothGattCharacteristic characteristic = gatt
                    .getService(ServiceUUID2)
                    .getCharacteristic(CharUUID2);
            gatt.readCharacteristic(characteristic);
        }
        Log.e(TAG,"onDescriptorWrite #1, Done!");
    }
};

private void broadcastUpdate(final String action) {
    final Intent intent = new Intent(action);
    sendBroadcast(intent);
}

private void broadcastUpdate(final String action,
                             final BluetoothGattCharacteristic characteristic,int device) {
    final Intent intent = new Intent(action);

    final byte[] data = characteristic.getValue();

    if (data != null && data.length > 0&&device ==0) {
        final StringBuilder stringBuilder = new StringBuilder(data.length);
        for(byte byteChar : data)
            stringBuilder.append(String.format("%02X ", byteChar));
        String DATA = stringBuilder.toString();
        Log.d(TAG,"MY DATA IN HEX " + DATA);
        String DecData =HexAsciiConverter.HexAscii2Decimal(DATA);
        Log.d(TAG,"MY DATA IN DECIMAL "+ DecData);
        intent.putExtra(EXTRA_DATA, " " + DecData);
    }
    else if( data != null && data.length > 0 && device ==1 ){
        final StringBuilder stringBuilder = new StringBuilder(data.length);
        for(byte byteChar : data)
            stringBuilder.append(String.format("%02X ", byteChar));
        String DATA = stringBuilder.toString();
        Log.d(TAG,"MY DATA IN HEX " + DATA);
        String DecData =HexAsciiConverter.HexAscii2Decimal(DATA);
        Log.d(TAG,"MY DATA IN DECIMAL "+ DecData);
        intent.putExtra(EXTRA_DATA1, " " + DecData);
    }
    sendBroadcast(intent);
}

public class LocalBinder extends Binder {
    BluetoothLeService getService() {
        return BluetoothLeService.this;
    }
}

@Override
public IBinder onBind(Intent intent) {
    return mBinder;
}

@Override
public boolean onUnbind(Intent intent) {
    close();
    return super.onUnbind(intent);
}

private final IBinder mBinder = new LocalBinder();

public boolean initialize() {
    // For API level 18 and above, get a reference to BluetoothAdapter through
    // BluetoothManager.
    if (mBluetoothManager == null) {
        mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        if (mBluetoothManager == null) {
            Log.e(TAG, "Unable to initialize BluetoothManager.");
            return false;
        }
    }

    mBluetoothAdapter = mBluetoothManager.getAdapter();
    if (mBluetoothAdapter == null) {
        Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
        return false;
    }

    return true;
}

public boolean connect(final String address,int devicenum) {
    if (mBluetoothAdapter == null || address == null) {
        Log.e(TAG, "BluetoothAdapter not initialized or unspecified address.");
        return false;
    }

    // Previously connected device.  Try to reconnect.
    if ((mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress))
            || (mBluetoothDeviceAddress1!=null && address.equals(mBluetoothDeviceAddress1))) {
        Log.e(TAG, "Trying to use an existing mBluetoothGatt for connection.");
        if (devicenum==0&&mBluetoothGatt.connect()) {
            mConnectionState = STATE_CONNECTING;
            return true;
        }
        else if(devicenum==1 && mBluetoothGatt1.connect()) {
            mConnectionState = STATE_CONNECTING;
            return true;
        }
        else{
            return false;
        }
    }

    final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
    if (device == null) {
        Log.e(TAG, "Device not found.  Unable to connect.");
        return false;
    }
    if(devicenum==0){
        mBluetoothGatt1 = device.connectGatt(this,false,mGattCallback);
        mBluetoothDeviceAddress= address;
        mConnectionState = STATE_CONNECTING;
        Log.e(TAG,"GATT CALLBACK #0 !  "+address);
    }
    else if(devicenum ==1){
        mBluetoothGatt = device.connectGatt(this, false, mGattCallback1);
        mBluetoothDeviceAddress1=address;
        mConnectionState = STATE_CONNECTING;
        Log.e(TAG,"GATT CALLBACK #1 !  "+address);
    }
    Log.e(TAG, "Trying to create a new connection.");
    return true;
}


public void disconnect() {
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
        Log.e(TAG, "BluetoothAdapter not initialized");
        return;
    }
    mBluetoothGatt.disconnect();

    if(mBluetoothGatt1!=null){
        mBluetoothGatt1.disconnect();
    }
}


public void close() {
    if (mBluetoothGatt == null) {
        return;
    }
    mBluetoothGatt.close();
    mBluetoothGatt1.close();
    mBluetoothGatt1 = null;
    mBluetoothGatt = null;
}

public void readCharacteristic(BluetoothGattCharacteristic characteristic,int device) {
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
        Log.e(TAG, "BluetoothAdapter not initialized");
        return;
    }
    if (device == 0) {
        mBluetoothGatt.readCharacteristic(characteristic);
    }
    else if(device ==1){
        mBluetoothGatt1.readCharacteristic(characteristic);
    }


}

public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled,int device) {
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
        Log.e(TAG, "BluetoothAdapter not initialized");
        return;
    }
    if(device == 0) {
        mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);

        BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
        descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
        mBluetoothGatt.writeDescriptor(descriptor);
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.e(TAG,"Device #0 is done for notification!");
    }
    else if(device == 1){
        mBluetoothGatt1.setCharacteristicNotification(characteristic,enabled);

        BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
        descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
        mBluetoothGatt.writeDescriptor(descriptor);
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.e(TAG,"Device #1 is done for notification!");
    }


}

public List<BluetoothGattService> getSupportedGattServices(int device) {
    if (mBluetoothGatt == null) return null;
    if(device ==0) {
        return mBluetoothGatt.getServices();
    }
    else {
        return mBluetoothGatt1.getServices();
    }
}

}

enter image description hereenter image description here

  • You are setting indications in your `setCharacteristicNotification` method, not notifications. These are different concepts and you have to use the correct one. have a look at this answer: https://stackoverflow.com/a/27075669/7473793 – Michael Kotzjan May 03 '21 at 04:47
  • Thanks for your help, dear M. Kotzjan. However, I tried "ENABLE_NOTIFICATION_VALUE". Still same, no data received (or displayed). This link (https://stackoverflow.com/questions/48705235/what-is-enable-indication-value-and-enable-notification-value-in-client-characte ) explains the difference between "indication" and "notification" as well. Any other suggestions, please? – Steven Wang May 03 '21 at 07:03
  • Can you add your log output to your question? – Michael Kotzjan May 03 '21 at 07:29
  • `if(devicenum==0){ mBluetoothGatt1` shouldn't this be mBluetoothGatt and vice versa? – Emil May 03 '21 at 08:35
  • Thanks @M. Kotzjan I have edited my question and added 2 screenshots for my Android Studio Logcat. It seems like page 1 (DeviceScanActivity) has no problem. The issues are inside page 2 (DeviceControlActivity.java and BluetoothLeService.java, see above 2 codes). – Steven Wang May 03 '21 at 23:37
  • Thank you @Emil Yes, this is a typo, I have fixed it. However, the issue still exists. I found there is no open-source code for multiple BLE device connections + receiving data. Therefore, hope this post and my codes code help other people, too. Thanks! – Steven Wang May 03 '21 at 23:40
  • @StevenWang there are more typos in your code. For example `setCharacteristicNotification` is only ever called with `device` set to 0. I would suggest you start enabling notifications for only one device and see if that works – Michael Kotzjan May 04 '21 at 04:20

0 Answers0