BLE получает уведомления GATT от характеристики

Я хочу получать уведомления при изменении этой характеристики Micro:Bit.

Я делаю в основном следующее:

1) Проверьте, совместима ли система с BLE.

2) Включить Bluetooth, если он отключен

3) Подключиться только к одному сопряженному устройству (Micro:Bit)

4) Активируйте этот код при изменении подключения (¿Подключено/Отключено?)

5) Активировать этот код при обновлении характеристики ¿?

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());
            }


        });

    }
}

}

У меня есть ошибка, что этот UUID "6E400003B5A3F393E0A9E50E24DCCA9E" имеет неверный формат. В любом случае, я не знаю, можно ли так подписаться на характеристику и получать уведомления.


person Lechucico    schedule 15.02.2018    source источник
comment
Ознакомьтесь с документацией по BLE. Попробуйте фрагмент, и если вы столкнетесь с проблемой в нем, задайте вопрос.   -  person Salman Naseem    schedule 15.02.2018


Ответы (1)


Просмотр документации для setCharacteristicNotification показывает только один конструктор

boolean setCharacteristicNotification (BluetoothGattCharacteristic characteristic, 
                boolean enable)

Итак, вам нужно сначала создать BluetoothGattCharacteristic из вашего UUID, например:

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);

Затем установите уведомления

gatt.setCharacteristicNotification(characteristic,true); 

Наконец, установите дескриптор конфигурации характеристик клиента, чтобы разрешить обновления, инициированные сервером.

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);

Последняя часть позволяет получать уведомления с устройства. UUID CCCD всегда один и тот же.

person Sanchit Anand    schedule 15.02.2018
comment
Но я хочу получать уведомления об этой характеристике, а не читать ее. Идея состоит в том, что он выполняет часть кода при получении уведомления. - person Lechucico; 15.02.2018
comment
Да, это то, что я пытаюсь показать вам в приведенном выше коде. Редактирование для уточнения. - person Sanchit Anand; 15.02.2018
comment
UUID для GattDescriptor какой? UUID для SerialService и SerialValue в вашем примере случайны, не так ли? Потому что те, что по этой ссылке, отличаются: lancaster-university.github. io/microbit-docs/ble/uart-сервис - person Lechucico; 15.02.2018
comment
См. правки выше. UUID дескриптора всегда один и тот же. Я рекомендую прочитать о протоколе BLE здесь - person Sanchit Anand; 15.02.2018
comment
Я посмотрю на эту ссылку. В любом случае, где можно найти UUID CONFIG_DESCRIPTOR? - person Lechucico; 15.02.2018
comment
Он должен быть одинаковым для каждого устройства. Попробуйте указанное выше значение. - person Sanchit Anand; 15.02.2018
comment
У меня есть следующая ошибка: java.lang.NullPointerException: попытка вызвать виртуальный метод «android.bluetooth.BluetoothGattCharacteristic android.bluetooth.BluetoothGattService.getCharacteristic (java.util.UUID)» для нулевой ссылки на объект. Кажется, этому не нравится мой UUID. СЛУЖБА = UUID.fromString(6E400001-B5A3-F393-E0A9-E50E24DCCA9E) и UUID.fromString(6E400003-B5A3-F393-E0A9-E50E24DCCA9E); - person Lechucico; 15.02.2018
comment
Я забыл упомянуть, что вам, возможно, придется также вызвать функцию discoveryServices(). Я считаю, что вам следует загрузить пример BLE для Android и несколько раз изучить код. - person Sanchit Anand; 15.02.2018
comment
Я использую DiscoverServices() в первую очередь, но все равно та же ошибка. - person Lechucico; 15.02.2018
comment
Я думаю, вам нужно установить свой код в функцию обратного вызова, а затем дождаться обнаружения всех служб. См. onServicesDiscovered(). - person Sanchit Anand; 15.02.2018
comment
Я использую onConnectionStateChange функцию gatt.disoverServices(), а затем устанавливаю обратный вызов onServicesDiscovered(), где я получаю характеристику, устанавливаю уведомления, получаю дескриптор и записываю дескриптор на сервер gatt... но все та же ошибка: java .lang.NullPointerException: попытка вызвать виртуальный метод 'android.bluetooth.BluetoothGattCharacteristic - person Lechucico; 19.02.2018