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.