1

I want to receive notifications when this characteristic is changed Micro:Bit.

What I'm doing is basically the following:

1) Check if the system is compatible with BLE

2) Enable bluetooth in case it's disabled

3) Connect to the only one paired device (Micro:Bit)

4) Activate this code when connectivity changes (¿Connected/Disconnected?)

5) Activate this code when characteristic is updated ¿?

public class MainActivity extends Activity {

BluetoothAdapter bleAdapter;

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

    **(1)**

    if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
        Toast.makeText(this, "BLE Not Supported", Toast.LENGTH_SHORT).show();
        finish();
    }

    **(2)**

    bleAdapter = ((BluetoothManager) getSystemService(BLUETOOTH_SERVICE)).getAdapter();

    if (bleAdapter == null || !bleAdapter.isEnabled()) {
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, 1);
    }

    Set<BluetoothDevice> pairedDevices = bleAdapter.getBondedDevices();

    for (BluetoothDevice device : pairedDevices) {

        **(3)**

        device.connectGatt(this, true, new BluetoothGattCallback() {

            **(4)**

            @Override
            public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
                super.onConnectionStateChange(gatt, status, newState);
                switch (newState) {
                    case BluetoothProfile.STATE_CONNECTED:
                        gatt.setCharacteristicNotification("6E400003B5A3F393E0A9E50E24DCCA9E", true); // This doesn't work
                        break;
                }
            }

            **5**

            @Override
            public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
                super.onCharacteristicChanged(gatt, characteristic);

                TextView x = (TextView) findViewById(R.id.x_axis);
                TextView y = (TextView) findViewById(R.id.y_axis);
                TextView z = (TextView) findViewById(R.id.z_axis);

                x.setText(characteristic.getValue().toString());
                y.setText(characteristic.getValue().toString());
                z.setText(characteristic.getValue().toString());
            }


        });

    }
}

}

I have an error that this UUID "6E400003B5A3F393E0A9E50E24DCCA9E" is malformed. Anyway, I don't know if this is how to subscribe to a characteristic and receive the notifications.

Lechucico
  • 1,914
  • 7
  • 27
  • 60
  • Check androdi BLE [documentation](https://developer.android.com/guide/topics/connectivity/bluetooth-le.html). Try the snippet and if you face problem in it then ask question. – Salman Naseem Feb 15 '18 at 15:46

1 Answers1

5

Looking at the documentation for setCharacteristicNotification reveals only one constructor

boolean setCharacteristicNotification (BluetoothGattCharacteristic characteristic, 
                boolean enable)

So, you need to first create a BluetoothGattCharacteristic from your UUID, for example :

public static final UUID SERIAL_SERVICE = UUID.fromString("0000ffe0-0000-1000-8000-00805f9b34fb");
public static final UUID SERIAL_VALUE  = UUID.fromString("0000ffe1-0000-1000-8000-00805f9b34fb");
BluetoothGattCharacteristic characteristic = gatt.getService(SERIAL_SERVICE).getCharacteristic(SERIAL_VALUE);

Then set notifications

gatt.setCharacteristicNotification(characteristic,true); 

Finally, set the Client Characteristic Config Descriptor to allow server initiated updates

public static final UUID CONFIG_DESCRIPTOR = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
BluetoothGattDescriptor desc = characteristic.getDescriptor(CONFIG_DESCRIPTOR);
desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(desc);

The last part enables you to receive notifications from the device. UUID of the CCCD is always the same.

Sanchit Anand
  • 195
  • 2
  • 11
  • But I want to get notified about this characteristic, not want to read it. The idea is that it executes a portion of code when a notification is reached. – Lechucico Feb 15 '18 at 15:41
  • Yes, that is what I am trying to show you in the code above. Editing for clarification. – Sanchit Anand Feb 15 '18 at 15:43
  • The UUID for GattDescriptor which is? The UUID for SerialService and SerialValue in your example are random, no? Because the ones from that link are different: https://lancaster-university.github.io/microbit-docs/ble/uart-service/ – Lechucico Feb 15 '18 at 15:57
  • See edits above. The descriptor UUID is always the same. I recommend reading about BLE protocol [here](https://www.safaribooksonline.com/library/view/getting-started-with/9781491900550/ch04.html#gatt_cccd) – Sanchit Anand Feb 15 '18 at 15:59
  • I'll take a look at this link. Anyway, the UUID CONFIG_DESCRIPTOR where can be found? – Lechucico Feb 15 '18 at 16:00
  • It should be the same for every device. Try the value above. – Sanchit Anand Feb 15 '18 at 16:06
  • I have the following error: java.lang.NullPointerException: Attempt to invoke virtual method 'android.bluetooth.BluetoothGattCharacteristic android.bluetooth.BluetoothGattService.getCharacteristic(java.util.UUID)' on a null object reference. It seems that this doens't like my UUID. SERVICE = UUID.fromString("6E400001-B5A3-F393-E0A9-E50E24DCCA9E") and UUID.fromString("6E400003-B5A3-F393-E0A9-E50E24DCCA9E"); – Lechucico Feb 15 '18 at 16:40
  • I forgot to mention that you may have to call discoverServices() function as well. I believe you should download the [Android BLE sample](https://github.com/googlesamples/android-BluetoothLeGatt) and examine the code a few times. – Sanchit Anand Feb 15 '18 at 16:48
  • I use discoverServices() on the first place, but still the same error. – Lechucico Feb 15 '18 at 16:51
  • I think you need to set your code in a callback function then to wait for all services to be discovered. See onServicesDiscovered() . – Sanchit Anand Feb 15 '18 at 17:01
  • I use onConnectionStateChange the function gatt.disoverServices() and then set a callback onServicesDiscovered() where I get the characteristic, set the notifications, get the descriptor, and write the descriptor to the gatt server... but still the same error: java.lang.NullPointerException: Attempt to invoke virtual method 'android.bluetooth.BluetoothGattCharacteristic – Lechucico Feb 19 '18 at 17:09