This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

[Android] Read characteristic while we subscribed to another

Hi everybody,

I'm currently writing an Android application allowing me to communicate with a NRF51422.

I've created on the Nordic chip one proprietary service with 2 characteristics:

  • The first one is working by notifying the smartphone;

  • The second one is read by the smartphone.

For the moment, it works fine when I activate only one of both actions but not when I try to do both at the same time. I read some topics explaining we need to have finished receiving previous data before doing anything else but I need to be able to receive this notification at any time...

Here is the class I wrote to handle my Bluetooth:

public class BluetoothModel {

private final static String TAG = "Model";

private  final static UUID SERVICE=UUID.fromString("00001523-1212-efde-1523-785feabcd123");
private final static  UUID CHARACTERISTIC_1=UUID.fromString("00001525-1212-efde-1523-785feabcd123");
private final static UUID CHARACTERISTIC_2=UUID.fromString("00001526-1212-efde-1523-785feabcd123");

public static UUID CLIENT_CHARACTERISTIC_CONFIG =UUID.fromString( "00002902-0000-1000-8000-00805f9b34fb");

private final static int ERR_BLE_ADAPTER_OR_HANDLER_NULL = 0x01;

private static BluetoothModel mBluetoothModel;

private static BluetoothAdapter mBluetoothAdapter;
private static BluetoothAdapter.LeScanCallback mLeScanCallback;
private static BluetoothGatt mConnectedGatt;

private static Handler mHandler;

private static BluetoothListener listener;

private static HashMap<String, BluetoothDevice> mapDevices;

public BluetoothModel()
{
    super();
    mHandler = new Handler();
}

public static BluetoothModel getInstance()
{
    // ...
}

public void initializeBluetooth(Context aContext)
{
    Log.i(TAG, "initializeBluetooth");
    if( !aContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE) )
    {
        listener.bluetoothIsNotSupported(new BluetoothIsNotSupportedEvent(this, false));
    }
    else
    {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if(mBluetoothAdapter == null)
        {
            listener.bluetoothAdapterNotFound(new BluetoothAdapterNotFoundEvent(this, false));
        }
        else
        {
            if(!mBluetoothAdapter.isEnabled())
            {
                Log.w(TAG, "Activation Bluetooth...");
                listener.bluetoothHasToBeEnable(new BluetoothHasToBeEnableEvent(this));
            }
        }
    }
}
    

public void addBluetoothListener( BluetoothListener listener )
{
    BluetoothModel.listener = listener;
}

public void scanForDevice()
{
    // ...
}

public void connectToDevice(String address, Context aContext)
{
    // ...
}

public void getCharacteristic_2() 
{
    Log.e(TAG, "getCharacteristic_2");

    if(!mConnectedGatt.readCharacteristic(mConnectedGatt.getService(SERVICE).getCharacteristic(CHARACTERISTIC_2)))
    {
        Log.e(TAG, "cannot read the characteristic_2");
    }
}

public static void disconnect()
{
    // ...
}

public BluetoothGatt getGatt()
{
    return mConnectedGatt;
}

// ------------------------------------------- CALLBACK BLE -------------------------------------------
private static BluetoothGattCallback mGattCallback = new BluetoothGattCallback()
{
    public void setNotify(BluetoothGatt gatt, BluetoothGattCharacteristic charac, boolean doNotify)
    {
        Log.i(TAG, "subscribing to a characteristic"+charac.getUuid());
        if(!doNotify)
        {
            gatt.setCharacteristicNotification(charac, false);
            BluetoothGattDescriptor desc = charac.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG);
            desc.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
            gatt.writeDescriptor(desc);
        }
        else
        {
            gatt.setCharacteristicNotification(charac, true);
            BluetoothGattDescriptor desc = charac.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG);
            desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            gatt.writeDescriptor(desc);
        }
    }

    // New services discovered
    public void onServicesDiscovered(BluetoothGatt gatt, int status)
    {
        if(status==BluetoothGatt.GATT_SUCCESS)
        {               
            Log.i(TAG,"onServicesDiscovered OK, Subscribing...");
            BluetoothGattCharacteristic carac=gatt.getService(SERVICE).getCharacteristic(CHARACTERISTIC_1);
            if(carac!=null)
            {
                setNotify(gatt,carac,true);
            }
        }
        else
        {
            Log.i(TAG,"onServicesDiscovered : failed. Disconnexion");
            disconnect();
        }
    }

    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status,int newState) 
    {
        // ...
    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic)
    {
        Log.i(TAG,"onCharacteristicChanged "+characteristic.getUuid().toString());
        if(characteristic.getUuid().equals(CHARACTERISTIC_1))
        {
            int value=characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0);                  
            boolean myBoolChar=true;
            if(value == 0)
            {
                myBoolChar=false;
            }
            listener.bluetoothMyBoolCharChanged(new bluetoothMyBoolCharChangedEvent(this, myBoolChar)); 
        }   
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic charac, int status)
    {
        Log.e(TAG, "onCharacteristicRead");
    }
    };
}

Here, characteristic_1 is the characteristic I receive using notifications and characteristic_2 is read. In this code, my problem happens when I call get_characteristic2() while notifications are enable on characteristic_1. Indeed, the callback onCharacteristicRead is never call...

Hopping I have been clear enough...

Harold.

Related