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

标签 android bluetooth bluetooth-lowenergy

我想读取存储在设备中的特征值,修改该值,然后将其写入设备。出于某种原因,writeCharacteristic() 返回 true,但内部设备值没有改变并且 onCharacteristicWrite() 没有被调用。事实上,出于某种原因,它在我试图写东西时被调用,然后在我关闭或重新打开应用程序后不久被调用 - 并且不会更改设备值。我已经研究了几天,这让我发疯。可能值得注意的是,手动和通过通知读取特征都可以正常工作。

为什么 writeCharacteristic() 没有通过,为什么 onCharacteristicWrite() 在如此奇怪的时间被调用?

我不确定问题出在哪里。它可能是愚蠢和简单的事情,比如错误地调用 writeCharacteristic()(我的实现基于问题“Working with BLE Android 4.3 how to write characteristics?”)。是否有可能因为 onCharacteristicRead() 未完成而忽略请求?

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

作为我的代码的演练,onItemClick() 事件被触发,该事件启动了序列。

int flag = 1;
((MainActivity)getActivity()).BtService.readFlag(flag);

它调用一个函数(在 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;
    }
}

onCharacteristicRead() 被调用,它只调用一个Handler 来修改并将结果广播回MainActivitytrueFlagValue 是一个字节,全局存储在 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;

MainActivity 中的 BroadcastReceiver 然后调用我的 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;
}

然后应调用我的 onCharacteristicWrite() 回调,目前仅包含一行代码来记录消息。实际上,这只会在应用程序关闭或重新打开时偶尔调用。存储在我的外设特性中的值永远不会改变。

最佳答案

我不是专家,但在我的 BLE 应用中

  • 我首先连接到外设
  • 然后与之配对(通过调用 createBond() 方法),
  • 然后发现服务,
  • 然后发现特征(并将它们存储在应用程序变量中)和
  • 最后将值写入特征(通过使用应用程序变量)

你试过吗?

关于android - writeCharacteristic() 返回 true,但不调用 onCharacteristicWrite(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30420137/

相关文章:

java - 在 Android 中显示来自休息服务器的 gif/动画 ImageView

bluetooth - 低功耗蓝牙供电设备能否发现经典蓝牙设备,反之亦然?

c++ - 无法使用 C++ 中的 Window 蓝牙 API 连接到蓝牙设备

linux - 使 linux-device (intel edison) 在另一个 linux 设备上可见以进行 BLE 扫描

java - 蓝牙 LE - 如何获得广告间隔(以毫秒为单位)?

android - 包含 ImageView 的 RecyclerView 项目上的波纹效果

android - 将 PlaceID 字符串转换为 LatLng 对象

android - 联想A600在应用程序被杀死后无法保持服务运行

android - 如何通过蓝牙从 PC 流式传输音频

android - 从广播接收器中的另一个类调用方法