我厌倦了使用Android BLE SDK与我的Glucose设备通信。
我需要UUID 2a18和2a34的setCharacteristicNotification。我指的是Android官方SDK,如下所示:
http://developer.android.com/guide/topics/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回调。
我的onCharacteristicChanged如下:
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);
};
});
}
如果我将电池电量通知设置如下,它将起作用。
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);
我不知道电池和葡萄糖通知有什么不同。
如果有人知道我该怎么办,请帮助我。
额外:
当我使用电池服务时,我的logcat如下:
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(),如下所示:
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()...
附加(8/4):
感谢您的回复 !
我试图在“记录访问控制点”特征上启用指示,但是失败了。
我的流程如下:
启用有关葡萄糖测量特征和葡萄糖测量上下文特征的通知
和
启用有关记录访问控制点特征的指示
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记录访问控制点
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;
我的回调函数
@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示例应用程序,它可以工作。
我尝试学习如何实现该功能。
我注意到LogCat上显示了一些类似“ unregisterIRListener()被调用”的日志,但是我不确定是否与我的问题有关...
谢谢阅读。
最佳答案
葡萄糖和电池服务在逻辑上有所区别。通常,当您启用电池电量通知时(取决于实现方式),设备会立即向您发送电池电量通知。这就是为什么您在那里进入通知。当然,在某些实现中,它仅在值更改时或使用其他规则时才通知您,但在您这种情况下,它的行为看起来像是这样。
葡萄糖服务的工作原理有所不同。在葡萄糖服务(https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.glucose.xml)中,您具有3个必需特征。让我们在这里跳过葡萄糖功能。
其中之一是葡萄糖测量,您可以在其中获取葡萄糖读数通知。您启用这些通知的实现是正确的,它将起作用。但是为了获得通知,您必须使用“记录访问控制点”特征来请求它们。它允许您获取所有葡萄糖读数,只有最新的,只有第一个,从设备等中删除保存的读数。例如,当您:
启用有关葡萄糖测量特征的通知(就像您所做的一样)
启用有关记录访问控制点特征的指示
发送f.e. 0x0101 =报告存储的记录|所有记录
您应该在“葡萄糖测量”字符上收到N条通知。然后在RACP字符上进行指示。值:0x06000101 =对“报告存储的记录”的响应|成功。
如果血糖仪上未保存任何读数,则N可以为0。如果您使用的是Nordic Semiconductor的葡萄糖服务示例应用程序,则可以尝试按按钮0(?)在板上生成新结果(最多20个),然后再次请求。
阅读GLS文档:https://www.bluetooth.org/en-us/specification/adopted-specifications-> GLS-> PDF,以获取有关葡萄糖服务和记录访问控制点格式的更多信息。
编辑
您正在写错误的记录访问控制点值。这是工作代码:
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个字节,您可能没有