葡萄糖的 Android BLE 通知 [英] Android BLE notifications for Glucose

查看:18
本文介绍了葡萄糖的 Android BLE 通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我厌倦了使用 Android BLE SDK 与我的 Glucose 设备进行通信.我需要 UUID 2a18 和 2a34 的 setCharacteristicNotification.我参考Android官方SDK如下:

I tired to use Android BLE SDK to communication with my Glucose device. I need setCharacteristicNotification for UUID 2a18 and 2a34. I refer to the Android official SDK as follows:

http://developer.android.com/guide/主题/连接/bluetooth-le.html#notification

BluetoothGattCharacteristic charGM = 
mConnGatt.getService(UUID.fromString(BleUuid.SERVICE_GLUCOSE))
    .getCharacteristic(UUID.fromString(BleUuid.CHAR_GLUCOSE_MEASUREMENT_STRING));
mConnGatt.setCharacteristicNotification(charGM, enabled);
BluetoothGattDescriptor descGM = charGM.getDescriptor(UUID.fromString(BleUuid.CHAR_CLIENT_CHARACTERISTIC_CONFIG_STRING));
descGM.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mConnGatt.writeDescriptor(descGM);

但它甚至无法进入 onCharacteristicChanged 回调.

BUT it can not even enter the onCharacteristicChanged callback.

我的 onCharacteristicChanged 如下:

my onCharacteristicChanged as follows:

        public void onCharacteristicChanged(BluetoothGatt gatt,
                                        BluetoothGattCharacteristic characteristic) {
        broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
        runOnUiThread(new Runnable() {
            public void run() {
                Toast.makeText(getApplicationContext(),"onCharacteristicChanged",Toast.LENGTH_LONG).show();
                setProgressBarIndeterminateVisibility(false);
            };
        });
    }

如果我将电池电量通知设置如下,它就可以工作.

if I set Battery Level notification as follows, it works.

BluetoothGattCharacteristic charBarrery = 
    mConnGatt.getService(UUID.fromString(BleUuid.SERVICE_BATTERY))
        .getCharacteristic(UUID.fromString(BleUuid.CHAR_BATTERY_LEVEL_STRING));
mConnGatt.setCharacteristicNotification(charBarrery, enabled);
BluetoothGattDescriptor descBarrery = charBarrery.getDescriptor(UUID.fromString(BleUuid.CHAR_CLIENT_CHARACTERISTIC_CONFIG_STRING));
descBarrery.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mConnGatt.writeDescriptor(descBarrery);

我不知道电池和葡萄糖通知有什么不同.

I dont know what is different with Battery and Glucose notifications.

如果有人知道我该怎么做,请帮助我.

If anyone knew what should I do, so please help me.

附加:

当我使用电池服务时,我的logcat如下:

when I used battery service, my logcat as follows:

07-29 10:28:17.924: D/BluetoothGatt(947): setCharacteristicNotification() - uuid: 00002a19-0000-1000-8000-00805f9b34fb enable: true
07-29 10:28:17.924: D/BluetoothGatt(947): writeDescriptor() - uuid: 00002902-0000-1000-8000-00805f9b34fb
07-29 10:28:18.484: D/BluetoothGatt(947): onDescriptorWrite() - Device=B4:AB:2C:06:9E:F4 UUID=00002a19-0000-1000-8000-00805f9b34fb
07-29 10:28:18.604: D/BluetoothGatt(947): onNotify() - Device=B4:AB:2C:06:9E:F4 UUID=00002a19-0000-1000-8000-00805f9b34fb

但是当我使用 Glucose 时,我的 logcat 丢失了 onNotify(),如下所示:

but when I use Glucose, my logcat lose onNotify(), like this:

07-29 10:31:23.729: D/BluetoothGatt(1763): setCharacteristicNotification() - uuid: 00002a18-0000-1000-8000-00805f9b34fb enable: true
07-29 10:31:23.729: D/BluetoothGatt(1763): writeDescriptor() - uuid: 00002902-0000-1000-8000-00805f9b34fb
07-29 10:31:24.324: D/BluetoothGatt(1763): onDescriptorWrite() - Device=B4:AB:2C:06:9E:F4 UUID=00002a18-0000-1000-8000-00805f9b34fb

我不知道为什么 logcat 丢失了 onNotify()...

I dont know why logcat lose the onNotify()...

附加(8/4):

感谢您的回复!我试图启用记录访问控制点特性的指示,但失败了..我的流程如下:

Thanks for your reply ! I tried to enable indications on Record Access Control Point characteristic but failed.. My Process as follows:

  1. 启用关于葡萄糖测量特征和葡萄糖测量上下文特征的通知&启用记录访问控制点特性的指示

  1. Enable notifications on Glucose Measurement characteristic and Glucose Measurement Context characteristic & Enable indications on Record Access Control Point characteristic

    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
    for (BluetoothGattService service : gatt.getServices()) {
        if ((service == null) || (service.getUuid() == null)) {
            continue;
        }
        if (BleUuid.SERVICE_GLUCOSE.equalsIgnoreCase(service
                .getUuid().toString())) {

            BluetoothGattCharacteristic charGM = 
                    mConnGatt.getService(UUID.fromString(BleUuid.SERVICE_GLUCOSE))
                        .getCharacteristic(UUID.fromString(BleUuid.CHAR_GLUCOSE_MEASUREMENT_STRING));
            mConnGatt.setCharacteristicNotification(charGM, enabled);
            BluetoothGattDescriptor descGM = charGM.getDescriptor(UUID.fromString(BleUuid.CHAR_CLIENT_CHARACTERISTIC_CONFIG_STRING));
            descGM.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            mConnGatt.writeDescriptor(descGM);

            BluetoothGattCharacteristic charGMC = 
                mConnGatt.getService(UUID.fromString(BleUuid.SERVICE_GLUCOSE))
                    .getCharacteristic(UUID.fromString(BleUuid.CHAR_GLUCOSE_MEASUREMENT_CONTEXT_STRING));
            mConnGatt.setCharacteristicNotification(charGMC, enabled);
            BluetoothGattDescriptor descGMC = charGMC.getDescriptor(UUID.fromString(BleUuid.CHAR_CLIENT_CHARACTERISTIC_CONFIG_STRING));
            descGMC.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            mConnGatt.writeDescriptor(descGMC);

            BluetoothGattCharacteristic charRACP = 
                mConnGatt.getService(UUID.fromString(BleUuid.SERVICE_GLUCOSE))
                    .getCharacteristic(UUID.fromString(BleUuid.CHAR_RECORD_ACCESS_CONTROL_POINT_STRING));
            mConnGatt.setCharacteristicNotification(charRACP, enabled);
            BluetoothGattDescriptor descRACP = charRACP.getDescriptor(UUID.fromString(BleUuid.CHAR_CLIENT_CHARACTERISTIC_CONFIG_STRING));
            descRACP.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
            mConnGatt.writeDescriptor(descRACP);

            BluetoothGattCharacteristic charBarrery = 
                    mConnGatt.getService(UUID.fromString(BleUuid.SERVICE_BATTERY))
                        .getCharacteristic(UUID.fromString(BleUuid.CHAR_BATTERY_LEVEL_STRING));
            mConnGatt.setCharacteristicNotification(charBarrery, enabled);
            BluetoothGattDescriptor descBarrery = charBarrery.getDescriptor(UUID.fromString(BleUuid.CHAR_CLIENT_CHARACTERISTIC_CONFIG_STRING));
            descBarrery.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            mConnGatt.writeDescriptor(descBarrery);

            runOnUiThread(new Runnable() {
                public void run() {
                    btnUpdateData.setEnabled(true);
                };
            });
        }
    }
};

  • 发送 0x0101 以记录访问控制点

  • Send 0x0101 to record access control point

        case R.id.btnUpdateData:
        try{
            //***SEND 0x0101 TO RECORD ACCESS CONTROL POINT   
            BluetoothGattCharacteristic writeRACPchar = 
                    mConnGatt.getService(UUID.fromString(BleUuid.SERVICE_GLUCOSE))
                        .getCharacteristic(UUID.fromString(BleUuid.CHAR_RECORD_ACCESS_CONTROL_POINT_STRING));
            byte[] data = new byte[1];
            data[0] = (byte)0x0101;
            writeRACPchar.setValue(data);
            mConnGatt.writeCharacteristic(writeRACPchar);
        }catch(Exception e){
            e.printStackTrace();
        }
        break;
    

  • 我的回调函数

  • my callback function

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt,
                                     BluetoothGattCharacteristic characteristic, 
                                     int status) {
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
    }
    
    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt,
            BluetoothGattCharacteristic characteristic, int status) {
    };
    
    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,
                                        BluetoothGattCharacteristic characteristic) {
        broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
    }
    

  • &

        private void broadcastUpdate(final String action,
            final BluetoothGattCharacteristic characteristic) {
            final Intent intent = new Intent(action);
            if (BleUuid.CHAR_SERIAL_NUMBEAR_STRING
                    .equalsIgnoreCase(characteristic.getUuid().toString())) {
                displayResult(characteristic.getStringValue(0));
            }else if(BleUuid.CHAR_MANUFACTURER_NAME_STRING
                    .equalsIgnoreCase(characteristic.getUuid().toString())){
                displayResult(characteristic.getStringValue(0));
            } else if(BleUuid.CHAR_BATTERY_LEVEL_STRING
                    .equalsIgnoreCase(characteristic.getUuid().toString())){
                final byte[] data = characteristic.getValue();
                String dataStr = "";
                dataStr = String.format("%02X", data[0]);
                int a = Integer.parseInt(dataStr, 16);
                String result = "battery level: " + Integer.toString(a)+ "%";
                displayResult(result);
            } else {
                // For all other profiles, writes the data formatted in HEX.
                final byte[] data = characteristic.getValue();
                if (data != null && data.length > 0) {
                    final StringBuilder stringBuilder = new StringBuilder(data.length);
                    for(byte byteChar : data)
                        stringBuilder.append(String.format("%02X ", byteChar));
                    displayResult(stringBuilder.toString());
                }
            }
    }
    

    &

        private void displayResult(String result){
        adUpdateData.add(result);
        runOnUiThread(new Runnable() {
            public void run() {
                lvUpdateData.setAdapter(adUpdateData);
            };
        });
    }
    

    我试图理解GLS_SPEC"pdf...我使用了 Nordic Semiconductor 的 Glucose Service 示例应用程序,它可以工作.我试着学习如何达到那个功能.

    I'm trying to understand that "GLS_SPEC" pdf... I used Nordic Semiconductor's Glucose Service sample application, and it could works. I try to learn how to reach that function.

    我注意到 LogCat 上显示了一些类似unregisterIRListener() 被调用"的日志,但我不确定是否关于我的问题...

    I noted some log like "unregisterIRListener() is called" shows on LogCat, but I'm not sure that whether about my question or not...

    感谢阅读.

    推荐答案

    葡萄糖和电池服务存在逻辑差异.通常,当您启用电池电量通知时(取决于实施),设备会立即向您发送电池电量.这就是你在那里得到 onNotify 的原因.当然,在某些实现中,它仅在值更改或其他规则时通知您,但在您的情况下,它的行为看起来像这样.

    there is a logical difference in Glucose and Battery service. When you enable Battery Level notifications usually (depending on the implementation) a device sends you battery level immediately. That's why you get onNotify there. Of course in some implementations it notifies you only when the value changes, or with other rule, but in you case it looks like it behaves like this.

    葡萄糖服务的工作方式不同.在葡萄糖服务 (https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.glucose.xml) 你有 3 个强制性特征.让我们在这里跳过葡萄糖功能.其中之一是葡萄糖测量,您可以在其中收到葡萄糖读数通知.您启用这些通知的实现是正确的,它将起作用.但是为了获得通知,您必须使用记录访问控制点特性来请求它们.它允许您获取所有葡萄糖读数,只有最新的,只有第一个,从设备中删除保存的读数等.例如,当您:

    Glucose service works different. In the Glucose Service (https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.glucose.xml) you have 3 mandatory characteristics. Let's skip the Glucose Feature here. One of them is Glucose Measurement where you get glucose reading notifications. Your implementation to enable these notifications is correct, it will work. But in order to get notifications you have to request for them using Record Access Control Point characteristic. It allows you to get all glucose readings, only the latest, only the first, delete saved readings from the device etc. For example, when you:

    1. 启用有关葡萄糖测量特征的通知(就像您所做的那样)
    2. 启用记录访问控制点特性的指示
    3. 发送 f.e.0x0101 = 报告存储的记录 |所有记录

    您应该会收到 N 个关于葡萄糖测量字符的通知.后跟在 RACP 字符上的指示.值:0x06000101 = 响应报告存储的记录"|成功.如果没有读数保存在葡萄糖设备上,N 可以是 0.如果您正在使用 Nordic Semiconductor 的葡萄糖服务示例应用程序,您可以尝试按下按钮 0(?) 在板上生成新结果(最多 20 个)并再次请求.

    you should get N notifications on Glucose Measurement char. followed by an indication on RACP char. with value: 0x06000101 = Response for "Report stored records" | success. N may be 0 if no readings are saved on the glucose device. If you're using Nordic Semiconductor's Glucose Service sample application you may try pressing button 0(?) to generate a new result on the board (up to 20) and request again.

    阅读 GLS 文档:https://www.bluetooth.org/en-us/specification/adopted-specifications -> GLS -> PDF 以获取有关葡萄糖服务和记录访问控制点格式的更多信息.

    Read the GLS documentation: https://www.bluetooth.org/en-us/specification/adopted-specifications -> GLS -> PDF for more information about Glucose Service and Record Access Control Point format.

    编辑

    您写错了记录访问控制点值.这是工作代码:

    You're writing the Record Access Control Point value wrong. Here's the working code:

    case R.id.btnUpdateData:
        try{
            //***SEND 0x0101 TO RECORD ACCESS CONTROL POINT   
            BluetoothGattCharacteristic writeRACPchar = 
                    mConnGatt.getService(UUID.fromString(BleUuid.SERVICE_GLUCOSE))
                        .getCharacteristic(UUID.fromString(BleUuid.CHAR_RECORD_ACCESS_CONTROL_POINT_STRING));
            byte[] data = new byte[2];
            data[0] = 0x01; // Report Stored records
            data[1] = 0x01; // All records
            writeRACPchar.setValue(data);
    
            // or:
            // byte[] data = new byte[2];
            // writeRACPchar.setValue(data);
            // writeRACPchar.setIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 1, 0); // Report Stored records
            // writeRACPchar.setIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 1, 1); // Read all (offset 1)
            mConnGatt.writeCharacteristic(writeRACPchar);
        }catch(Exception e){
            e.printStackTrace();
        }
        break;
    

    你必须写 2 个字节,每个字节是 8 个但可以写成 2 位十六进制,例如0xAB r 0x01.值 0x0101 有 2 个字节,您可能不会

    You have to write 2 bytes, each byte is 8 buts which may be written as 2-digit HEX, f.e. 0xAB r 0x01. The value 0x0101 has 2 bytes and you may not

    这篇关于葡萄糖的 Android BLE 通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆