java - bluetoothGatt.writeCharacteristic 总是返回 false,ble 特征类型为 write_no_reponse
问题描述
我正在编写一个 Android 应用程序来与 BLE 仪表交谈。我已经能够扫描设备、连接到目标、发现服务、获取特征。但是,当我尝试编写 write_no_reponse 特性时,该方法总是返回 false。我确信特征是可写的,我使用其他应用程序来做。当我调试到android.bluetooth代码时,出现如下顺序失败,可能是返回了一个空服务,调试运行到这一步再跳出方法:
BluetoothGattService service = characteristic.getService();
这会导致 writeCharacteristic 返回 false。但是在writeCharacteristic之前,我有一个日志
Log.d(TAG, "onServicesDiscovered: writeType" + mCharacteristic.getService());
bluetoothGatt.writeCharacteristic(mCharacteristic);
并且日志正确,不返回null;
任何帮助是极大的赞赏!
并且我使用相同的代码写入一个 WRITE 特性,它起作用了。我尝试使用
mCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
设置写入类型,但它也失败了。
写入数据代码:
public void writeReadDataCommand() {
if (null != bluetoothGatt) {
mCharacteristic.setValue("123123");
bluetoothGatt.setCharacteristicNotification(mCharacteristic, true);
mCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
Log.d(TAG, "onServicesDiscovered: writeType" + mCharacteristic.getService());
boolean isWrite = bluetoothGatt.writeCharacteristic(mCharacteristic);
if (isWrite) {
Log.d(TAG, "writeReadDataCommand: write data to BLE");
}
}
}
onServiceDiscovered 代码:
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
bluetoothGatt = gatt;
BluetoothGattService service = gatt.getService(UUID.fromString(SERVICE_UUID));
BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString(CHARACTERISTIC_UUID));
Log.d(TAG, "onServicesDiscovered: writeType" + characteristic.getWriteType());
boolean isSuccess = gatt.setCharacteristicNotification(characteristic, true);
if (isSuccess) {
mCharacteristic = characteristic;
List<BluetoothGattDescriptor> descriptors = characteristic.getDescriptors();
if (null != descriptors && descriptors.size() > 0) {
for (BluetoothGattDescriptor descriptor : descriptors) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);
}
}
}
connectCallback.findService();
} else {
Log.d(TAG, "onServicesDiscovered received: " + status);
}
}
并且 onCharacteristicWrite 回调不会触发
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
Log.d(TAG, "onCharacteristicWrite: " + Arrays.toString(characteristic.getValue()));
}
这个bug很久了,如果有人能帮忙,非常感谢。
解决方案
在 onDescriptorWrite() 之后将数据发送到 BLE 设备。
private final BluetoothGattCallback getGattCallback1=new BluetoothGattCallback() {
@Override
public void onPhyUpdate(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
super.onPhyUpdate(gatt, txPhy, rxPhy, status);
}
@Override
public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
super.onPhyRead(gatt, txPhy, rxPhy, status);
}
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
}
@Override
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorRead(gatt, descriptor, status);
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorWrite(gatt, descriptor, status);
// here send broadcast to MainActivity.That u are ready to write Data To the device.
}
@Override
public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
super.onReliableWriteCompleted(gatt, status);
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
super.onReadRemoteRssi(gatt, rssi, status);
}
@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
super.onMtuChanged(gatt, mtu, status);
}
};
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public void setCharacteristicNotifications(BluetoothGatt bluetoothGatt,BluetoothGattCharacteristic characteristic,
boolean enabled,String bleAddress) {
if (mBluetoothAdapter == null || bluetoothGatt == null) {
return;
}
bluetoothGatt.setCharacteristicNotification(characteristic, enabled);
BluetoothGattDescriptor descriptor = null;
descriptor = characteristic.getDescriptor(UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG));
if (descriptor == null) {
enableNotiticationToFirmwareCompleted(false,bleAddress);
return;
}
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
bluetoothGatt.writeDescriptor(descriptor);
}
推荐阅读
- javascript - 单击时我想显示按钮,再次单击时我想隐藏按钮
- api - 使用iis上传大文件.net core 3.1 api而不更改web.config
- python - 如何更改matplotlib z轴上所有点的颜色?
- php - Laravel updateOrCreate 与 hasMany 关系
- python - python tkinter 你的 SQL 语法有错误
- python - 无法使用 conda 部署到 heroku,requirements.txt 失败
- batch-file - 使用 Edge 从批处理文件全屏启动 Powerapp
- css - 如何在 laravel 8 中安装引导程序
- python - 通过 lambda 函数读取 AWS S3 存储桶中的 .tif 文件,这些文件包含在另一个目录中
- php - 我可以在 php mysqli_prepare 中使用 IF NOT EXISTS SELECT 吗?