writeCharacteristic()返回true,但不调用onCharacteristicWrite()

clb*_*355 7 android bluetooth bluetooth-lowenergy

我希望读取存储在设备中的特征值,修改该值,然后将其写入设备.由于某种原因,writeCharacteristic()返回true,但内部设备值不会更改,onCharacteristicWrite()也不会被调用.实际上,出于某种原因,只有在我尝试编写某些内容时才调用它,然后在关闭或重新打开应用程序后不久调用它 - 并且不会更改设备值.我一直在调查这几天,这让我发疯.值得注意的是,手动和通过通知读取特征都可以正常工作.

为什么writeCharacteristic()没有通过,为什么onCharacteristicWrite()在这么奇怪的时间被召唤?

我不确定问题源于何处.它可能是一些愚蠢和简单的东西,如writeCharacteristic()错误地调用(我的实现是基于" 使用BLE Android 4.3如何编写特征? "的问题).请求是否可能被忽略,因为onCharacteristicRead()某种程度上未完成?

我相信这些链接似乎对指出问题最有帮助,但我自己无法从中提取任何内容:

作为我的代码的演练,会触发一个onItemClick()事件,启动序列.

int flag = 1;
((MainActivity)getActivity()).BtService.readFlag(flag);
Run Code Online (Sandbox Code Playgroud)

它调用一个函数(在a中Service),它验证蓝牙连接并读取特征.

public boolean readFlag(int flag){
    /*... removed code here verifies that the Bluetooth Gatt is available,
    that the Service exists...*/

    BluetoothGattCharacteristic characteristic = Service.getCharacteristic(SEND_FLAGS_CHAR);

    if (characteristic == null) {
        Log.e(TAG, "char not found!");
        return false;
    }

    try {
        // Store intended flag value in SharedPreferences, then read the current one.
        Editor fEditor = sPrefs.edit();
        fEditor.putInt(calibrationSetFlagToSendKey, flag);
        fEditor.commit();

        mConnectedGatt.readCharacteristic(characteristic);

        // Catch response in onCharacteristicRead() callback.
        return true;
    }
    catch (NullPointerException e) {
        Log.w("readCharacteristic", "The characteristic could not be read.");
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

onCharacteristicRead()被调用,它只调用a Handler来修改和广播结果MainActivity.trueFlagValue是一个全局存储的字节Service(我知道的不好的做法,但我打算稍后修改它.)

case MSG_SEND_FLAG:
    characteristic = (BluetoothGattCharacteristic) msg.obj;
    if (characteristic.getValue() == null) {
        Log.w(TAG, "Error obtaining current flags");
        return;
    }

    int recentReadDeviceFlag = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0);
    int initialFlag = sPrefs.getInt(calibrationSetFlagToSendKey, 0);
    if (initialFlag == 0) Log.e("Write Debug", "Flag to send is apparently 0");

    /*... Arithmetic modifying flag integer value...*/
    //Desired value is the OR'd value of the value read and value desired
    trueFlagValue = (byte) ((byte) initialFlag | (byte) recentReadDeviceFlag);
    Log.d("Read Debug", "OR'd value is " + trueFlagValue +", sending broadcast");
    Intent fIntent = new Intent("com.example.appwithble.SEND_FLAGS");
    sendBroadcast(fIntent);
    break;
Run Code Online (Sandbox Code Playgroud)

BroadcastReceiverMainActivity随后我调用一个方法Service,验证了一个要求writeCharacteristic(),因为是为完成readCharacteristic().trueFlagValue先前访问该集.

    else if("com.example.appwithble.SEND_FLAGS".equals(intent.getAction())) {
        BtService.performWriteFlag();
    }

// ...

public boolean performWriteFlag () {
    /*... check Gatt is available and that Service exists...*/
    BluetoothGattCharacteristic characteristic = Service.getCharacteristic(SEND_FLAGS_CHAR);

    if (characteristic == null) {
        Log.e(TAG, "char not found!");
        return false;
    }

    byte[] byteValue = new byte[1];
    byteValue[0] = trueFlagValue;
    characteristic.setValue(byteValue);

    boolean status = mConnectedGatt.writeCharacteristic(characteristic);
    return status;
}
Run Code Online (Sandbox Code Playgroud)

onCharacteristicWrite()然后应该调用我的回调,并且当前只包含一行代码来记录消息.实际上,有时只会调用此应用程序,因为应用程序已关闭或重新打开.存储在我的外围设备特性中的值永远不会改变.

clb*_*355 0

这是一个菜鸟错误。

由于我没有尝试过写入数据,所以我认为写入过程或设备出了问题。在查看了来自的数据类型readCharacteristic()并询问了我要发送到的设备后,我开始意识到我发送的数据可能格式错误。

事实证明,即使只需要发送四个不同的标志(可以用两位完成),对于我的特定设备,该特征需要格式化为两个字节,而不是一个。因此,如果我将字节数组做成这样的东西,它就会起作用。

byte[] byteValue = new byte[2];
byteValue[0] = trueFlagValue;
byteValue[1] = (byte)0;
characteristic.setValue(byteValue);
Run Code Online (Sandbox Code Playgroud)

我希望如果其他人遇到奇怪的问题,即写入已启动但未完成,那么很可能是这样的问题 - 至少设备中的某些内容拒绝写入。