Android 低功耗蓝牙 - 读取浮点特性
Android Bluetooth LE - Read float characteristic
我正在尝试读取已连接的低功耗蓝牙设备 (Genuino 101) 的浮点特性。出于测试目的,设备提供了一个硬编码值为“55.3”的 FloatCharacteristic。虽然我能够接收到某种类似于浮点数的字符串,但我无法读取实际的浮点值。
这是处理字符串的代码片段:
// 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));
intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString());
}
这是直接从 android 开发者主页的 https://developer.android.com/samples/BluetoothLeGatt/index.html BLE 演示项目复制而来的。
然后由以下代码段处理意图:
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("Broadcast received");
final String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
}
}
};
private void displayData(String data) {
if (data != null) {
System.out.println("Data Received: " + data);
}
}
这导致输出
I/System.out: Data Received: 33]B
I/System.out: 33 33 5D 42
因此,抛开交换的字节序,这是 55.3f 的正确十六进制值。
但是,如果我尝试使用 characteristic.getFloatValue(),我只会得到垃圾。以下是我尝试弄清楚如何接收实际浮点数的方法:
final byte[] data = characteristic.getValue();
if (data != null && data.length > 0) {
for (int i = 0; i< 333; i++) {
try {
final float fData = characteristic.getFloatValue(BluetoothGattCharacteristic.FORMAT_FLOAT, i);
System.out.println("Offset = "+ i + ". Data that gets sent: " + fData + "/Data that we would expect: " + 55.3f);
} catch (Exception e) {
System.out.println("Exception at offset " + i);
}
}
}
输出总是
I/System.out: Offset = 0. Data that gets sent: Infinity/Data that we would expect: 55.3
I/System.out: Exception at offset 1
I/System.out: Exception at offset 2
...
我这里的错误是什么?另外,我不确定应该如何理解 Offset 参数。它是以位为单位,以字节为单位的偏移量吗?从 MSB 计数,从 LSB 计数?
getFloatValue() 的文档也声称 "returns float - Cached value of the characteristic at a given offset or null if the requested offset exceeds the value size. "。但是上面的代码片段严重超过了任何 gatt 特征的最大大小,但方法调用没有返回 'null',而是抛出异常。
那么这里获得浮动的正确方法是什么?
目前,我通过
格式化数据来帮助自己
float f1 = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).getFloat();
.
我正在尝试读取已连接的低功耗蓝牙设备 (Genuino 101) 的浮点特性。出于测试目的,设备提供了一个硬编码值为“55.3”的 FloatCharacteristic。虽然我能够接收到某种类似于浮点数的字符串,但我无法读取实际的浮点值。
这是处理字符串的代码片段:
// 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));
intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString());
}
这是直接从 android 开发者主页的 https://developer.android.com/samples/BluetoothLeGatt/index.html BLE 演示项目复制而来的。 然后由以下代码段处理意图:
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("Broadcast received");
final String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
}
}
};
private void displayData(String data) {
if (data != null) {
System.out.println("Data Received: " + data);
}
}
这导致输出
I/System.out: Data Received: 33]B
I/System.out: 33 33 5D 42
因此,抛开交换的字节序,这是 55.3f 的正确十六进制值。
但是,如果我尝试使用 characteristic.getFloatValue(),我只会得到垃圾。以下是我尝试弄清楚如何接收实际浮点数的方法:
final byte[] data = characteristic.getValue();
if (data != null && data.length > 0) {
for (int i = 0; i< 333; i++) {
try {
final float fData = characteristic.getFloatValue(BluetoothGattCharacteristic.FORMAT_FLOAT, i);
System.out.println("Offset = "+ i + ". Data that gets sent: " + fData + "/Data that we would expect: " + 55.3f);
} catch (Exception e) {
System.out.println("Exception at offset " + i);
}
}
}
输出总是
I/System.out: Offset = 0. Data that gets sent: Infinity/Data that we would expect: 55.3
I/System.out: Exception at offset 1
I/System.out: Exception at offset 2
...
我这里的错误是什么?另外,我不确定应该如何理解 Offset 参数。它是以位为单位,以字节为单位的偏移量吗?从 MSB 计数,从 LSB 计数? getFloatValue() 的文档也声称 "returns float - Cached value of the characteristic at a given offset or null if the requested offset exceeds the value size. "。但是上面的代码片段严重超过了任何 gatt 特征的最大大小,但方法调用没有返回 'null',而是抛出异常。 那么这里获得浮动的正确方法是什么?
目前,我通过
格式化数据来帮助自己 float f1 = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).getFloat();
.