首页 > 解决方案 > 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很久了,如果有人能帮忙,非常感谢。

标签: javaandroidandroid-ble

解决方案


在 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);

     }

推荐阅读