Android BLE同时写入和通知

时间:2018-07-15 03:23:26

标签: java android multithreading bluetooth-lowenergy android-bluetooth

我目前正在尝试将手机连接到Scale,并通过TI CC254X蓝牙4.0芯片的UART服务不断发送其数据,现在我已经可以使用大多数应用程序了。规模发送18位数组,我将其转换为字符串以进行处理,该数组工作正常,问题是尝试向其发送命令时遇到了问题。 注意:如果秤不能持续广播数据,程序可以发送命令并获得正确的响应。

当前,一旦程序检测到已连接到秤,它将运行以下命令:

sendCommand(OperationClass.getInstance().getGetTareCommand());
sendContinuousCommand(StatusClass.getInstance().getReadNetCommand());

翻译成这样:

private void addPacketToQueue(BluetoothGattCharacteristic characteristic, byte[] data){
        WritePacket newPacket = new WritePacket(characteristic, data);
        writeBuffer.add(newPacket);
}

protected void sendCommand(ScaleCommand commandAction) {
    byte[] command = ScaleCommandParser.getCommand(commandAction).getBytes();
    addPacketToQueue(writeCharacteristic, command);
}

protected void sendContinuousCommand(ScaleCommand commandAction) {
    byte[] command = ScaleCommandParser.getParameterisedCommand(OperationClass.getInstance().getRepeatCommand(), commandAction.getCommandId()).getBytes();
    addPacketToQueue(writeCharacteristic, command);

}

之后,我尝试将值实际写入特性:

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        super.onConnectionStateChange(gatt, status, newState);
        connectionState = newState;

        switch (newState) {
            case BluetoothProfile.STATE_CONNECTED:
                gatt.discoverServices();
                break;

            case BluetoothProfile.STATE_DISCONNECTED:
                connecting = false;
                gatt.disconnect();
                break;

            default:
                break;
        }

    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        super.onServicesDiscovered(gatt, status);
        BluetoothGattCharacteristic characteristic = gatt.getService(UUIDCommsService).getCharacteristic(UUIDCommsChar);
        if (characteristic == null) {
            return;
        }

        writeCharacteristic = characteristic;
        gatt.setCharacteristicNotification(writeCharacteristic, true);

        BluetoothGattDescriptor descriptor = writeCharacteristic.getDescriptor(UUIDClientConfig);
        descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        gatt.writeDescriptor(descriptor);
    }

    @Override
    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
        super.onDescriptorWrite(gatt, descriptor, status);
        onSuccessfulConnect();
        sendCommands();
    }


    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
        super.onCharacteristicChanged(gatt,characteristic);
        updateStatus(characteristic);
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        super.onCharacteristicChanged(gatt,characteristic);
        updateStatus(characteristic);
    }

    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        super.onCharacteristicChanged(gatt,characteristic);
        gatt.executeReliableWrite();
        updateStatus(characteristic);
    }
};

private void updateStatus(BluetoothGattCharacteristic characteristic){
    if (characteristic.equals(writeCharacteristic)) {
        ScaleResponse scaleResponse = ScaleResponseParser.processScaleResponse(characteristic.getValue());
        if (scaleResponse != null) {
            try {
                updateState(scaleResponse);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    sendCommands();
}
private void sendCommands(){
    sendingCommands = true;
    if (writeBuffer.size() > 0) {
        if (writeCharacteristic == null || bluetoothGatt == null)
            return;
        WritePacket packet = writeBuffer.getFirst();
        BluetoothGattCharacteristic characteristicToUpdate = packet.getTargetChar();
        characteristicToUpdate.setValue(packet.getData());
        bluetoothGatt.beginReliableWrite();
        if (bluetoothGatt.writeCharacteristic(characteristicToUpdate)) {
            writeBuffer.removeFirst();
        }
    }
    sendingCommands = false;

}

问题在于 onCharacteristicChanged 回调阻止了任何写入,因为它的更新非常快。我一直在谷歌搜索,但没有找到解决方案,有人有任何建议吗?我一直在使用https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal这个应用程序测试命令,即使在不断从电子秤接收数据的情况下,我也可以随时编写命令。

1 个答案:

答案 0 :(得分:-1)

我认为您的写作方式可能有问题。

onCharacteristicWrite表示特征写入操作的结果

在您的setValue()之后称为。您想做的是:

  1. 执行首次写入操作(setValue)
  2. 等待onCharacteristicWrite回调指示成功写入
  3. 执行第二次写操作(setValue)
  4. 等待onCharacteristicWrite回调