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

查看:91
本文介绍了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/topic/connectivity/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);

我不知道Battery和Glucose通知有什么区别.

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

但是当我使用葡萄糖时,我的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. 发送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/采用的规范-> 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天全站免登陆