更新
我正在尝试从连接到arduino设置的HM-10蓝牙设备接收恒定的串行数据流。我在Google Play商店中使用BLE扫描仪查找MAC地址和UUID。有一个特征可以读,写和通知。在应用程序上启用通知允许显示恒定的数据流,同时读取显示地址。我无法弄清楚启用通知如何允许访问数据流。我编写的代码使我能够连续阅读(显示地址,就像应用程序一样),并且我想知道如何访问通知数据。对不起,如果我的术语有误,我就不太了解BLE通知。这是我的Connect,Runnable和Callback代码:
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public void Connect(View view) throws InterruptedException {
Device = Adapter.getRemoteDevice("3C:A3:08:94:C3:11");
Gatt = Device.connectGatt(this, true, GattCallback);
}
private final BluetoothGattCallback GattCallback = new BluetoothGattCallback() {
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
Gatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
Service = Gatt.getService(UUID.fromString("0000FFE0-0000-1000-8000-00805F9B34FB"));
Characteristic = Service.getCharacteristic(UUID.fromString("0000FFE1-0000-1000-8000-00805F9B34FB"));
Gatt.setCharacteristicNotification(Characteristic, true);
thread.start();
} else {
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
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));
}
final String strReceived = stringBuilder.toString();
ErrorID.setText(strReceived);
}
}
};
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public void run() {
UUID uuid = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
BluetoothGattDescriptor descriptor = Characteristic.getDescriptor(uuid);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
Gatt.writeDescriptor(descriptor);
while (true) {
Gatt.readCharacteristic(Characteristic);
}
}
很抱歉,如果代码不是很清楚",
谢谢!
答案 0 :(得分:1)
删除读取具有100%cpu使用率的特征的while循环。编写描述符后写的setCharacteristicNotification就是为通知做准备所需的全部内容。
只需实现onCharacteristicChanged回调,然后在每次通知时调用它。
答案 1 :(得分:0)
<强>更新强>
所以我现在让textView显示来自蓝牙模块的数据。现在的问题是除非调用Connect方法,否则值不会更新(我按下连接按钮)。我怀疑这是因为达到了20个字节的限制。有没有办法让我在不重新连接的情况下不断更新数值?我还试图在显示时将值保存在文本文件中,但我的文本文件为空。这是我更新的代码:
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public void Connect(View view) throws InterruptedException {
Device = Adapter.getRemoteDevice("3C:A3:08:94:C3:11");
Gatt = Device.connectGatt(this, true, GattCallback);
}
private final BluetoothGattCallback GattCallback = new BluetoothGattCallback() {
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
Gatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
Service = Gatt.getService(UUID.fromString("0000FFE0-0000-1000-8000-00805F9B34FB"));
Characteristic = Service.getCharacteristic(UUID.fromString("0000FFE1-0000-1000-8000-00805F9B34FB"));
UUID uuid = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
descriptor = Characteristic.getDescriptor(uuid);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
Gatt.setCharacteristicNotification(Characteristic, true);
Gatt.writeDescriptor(descriptor);
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
final String strReceived = characteristic.getStringValue(0);
try {
FileOutputStream fos = new FileOutputStream(myFile);
OutputStreamWriter osw = new OutputStreamWriter(openFileOutput("Test.txt", MODE_APPEND));
osw.write(strReceived);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
ErrorID.setText(strReceived);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
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));
}
final String strReceived = stringBuilder.toString();
ErrorID.setText(strReceived);
}
}
};
答案 2 :(得分:0)
你可以增加最大值。使用OnServicesDiscovered Callback方法中的以下代码行对数据包进行字符限制:
mBluetoothGatt.requestMtu(80);
代替&#39; 80&#39;输入您计划接收的最大字节数。
然后在BluetoothGattCallback中,您希望包含以下案例和系统日志打印,以确认您已成功更新字符限制:
public void onMtuChanged(BluetoothGatt bluetoothGatt, int mtu, int status){
System.out.println(" +++++++ MTU CHANGE SUCCESSFUL +++++++");
}
至于通过通知接收串行数据&#39;我无法帮助,因为我一直在努力寻找一个简单的解释,说明如何做好这几周......