【问题标题】:Reading from a BluetoothGattCharacteristic is failing从 BluetoothGattCharacteristic 读取失败
【发布时间】:2016-09-28 01:02:08
【问题描述】:

我试图读取存储在BluetoothGattCharacteristic 中的值。以下是我的BluetoothGattCallback 代码,大部分操作都发生在这里:

 private final BluetoothGattCallback mGattCallback =
            new BluetoothGattCallback() {
                @Override
                public void onConnectionStateChange(BluetoothGatt gatt, int status,
                                                    int newState) {
                    if (newState == BluetoothProfile.STATE_CONNECTED) {
                        Log.i(TAG, "Connected to GATT server.");
                        Log.i(TAG, "Getting services....");
                        gatt.discoverServices();
                    } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                        Log.i(TAG, "Disconnected from GATT server.");
                    }
                }

                @Override
                public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                    if (status == BluetoothGatt.GATT_SUCCESS) {
                        BluetoothGattService serv = gatt.getService(Constants.MY_UUID);
                        if (serv != null) {
                            BluetoothGattCharacteristic characteristic = serv.getCharacteristic(Constants.ANOTHER_UUID);
                            boolean res = gatt.readCharacteristic(characteristic);
                            if (res) {
                                Log.d(TAG, "res was true");
                            } else {
                                Log.d(TAG, "res was false");
                            }
                        }
                    } else {
                        Log.w(TAG, "onServicesDiscovered received: " + status);
                    }
                }

                @Override
                public void onCharacteristicRead(BluetoothGatt gatt,
                                                 BluetoothGattCharacteristic characteristic,
                                                 int status) {
                    if (status == BluetoothGatt.GATT_SUCCESS) {
                        Log.d(TAG, "Succesfully read characteristic: " + characteristic.getValue().toString());
                    } else {
                        Log.d(TAG, "Characteristic read not successful");
                    }
                }
            };

所以要从特征中读取,我正在尝试使用gatt.readCharacteristic() 方法,该方法采用特征并返回指示操作成功与否的布尔值。在这里,这个方法返回false(打印“res was false”),表明它失败了。

没有打印错误信息。阅读特征的正确方法是什么?为什么这个方法会返回false

编辑: 按照 Inferno 的建议,继续下载所需的源代码,然后在 BluetoothGatt readCharacteristic() 方法中设置断点:

这是 android-23..\BluetoothGatt 中的 readCharacteristic() 方法

public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) {
        if ((characteristic.getProperties() &
                BluetoothGattCharacteristic.PROPERTY_READ) == 0) return false;

(characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_READ) 返回 0,所以 false 会立即返回。现在根据调试器characteristic.getProperties() 的返回值为8,而BluetoothGattCharacteristic.PROPERTY_READ 的静态int 值为0x02

据我了解,0x08 & 0x02 == 0。由于PROPERTY_READ 是硬编码值,我认为characteristic.getProperties() 返回的值有问题。这里可能出了什么问题?

【问题讨论】:

  • 即使gatt.readCharacteristic()返回false,回调onCharacteristicRead()也会发生吗?
  • 不,它不会被调用。
  • 我会更新我的答案,请稍等

标签: android bluetooth-lowenergy android-bluetooth android-ble


【解决方案1】:

阅读特征的正确方法是什么?

首先,您从onServicesDiscovered() 回调内部调用gatt.readCharacteristic(characteristic),这没关系。我看不出你的代码有任何严重的缺陷。

您可以在onConnectionStateChange() 中添加的内容是在验证newState == BluetoothProfile.STATE_CONNECTED 之前 进行额外检查:

if (status == BluetoothGatt.GATT_SUCCESS) { ...

为什么这个方法会返回 false?

我检查了BluetoothGatt here 的android 源代码,结果false 的返回值在许多不同的情况下都会返回,如下面的代码所示:

public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) {
    if ((characteristic.getProperties() &
            BluetoothGattCharacteristic.PROPERTY_READ) == 0) return false;

    if (VDBG) Log.d(TAG, "readCharacteristic() - uuid: " + characteristic.getUuid());
    if (mService == null || mClientIf == 0) return false;

    BluetoothGattService service = characteristic.getService();
    if (service == null) return false;

    BluetoothDevice device = service.getDevice();
    if (device == null) return false;

    synchronized(mDeviceBusy) {
        if (mDeviceBusy) return false;
        mDeviceBusy = true;
    }

    try {
        mService.readCharacteristic(mClientIf, device.getAddress(),
            characteristic.getInstanceId(), AUTHENTICATION_NONE);
    } catch (RemoteException e) {
        Log.e(TAG,"",e);
        mDeviceBusy = false;
        return false;
    }

    return true;
}

所以我建议你做的是,在 Android Studio 中启动调试器并在 readCharacteristic() 方法中设置一个断点(在 BluetoothGatt.java 中)并仔细单步执行代码以查看在哪里false 被退回。这样,您就有希望将问题本地化。除此之外,其他任何事情都将是疯狂的猜测。

当然,您需要下载源才能查看BluetoothGatt.java。但 Android Studio 会在编辑器顶部为您提供一个黄色小栏,询问您是否要下载和安装。只需执行此操作并在下载完成后重新启动 Android Studio。然后你应该可以在BluetoothGatt.java中设置断点。

更新:

据我了解,0x08 & 0x02 == 0。由于 PROPERTY_READ 是 硬编码值,我认为返回的值有问题 来自特征.getProperties()。这里可能出了什么问题?

根据 BLUETOOTH SPECIFICATION 版本 4.2 [Vol 3, Part G] 第 533 页,characteristic.getProperties() 返回的 0x8 的值表示您的特征具有只写权限。所有阅读尝试都失败并不奇怪。换句话说:您的蓝牙设备不允许您读取该特定特征。

引自规范:

特征属性位域确定特征值如何 可以使用,或者如何使用特征描述符(参见第 3.3.3 节) 访问。

【讨论】:

  • 我打开readCharacteristic()方法并下载了源代码,但由于某些奇怪的原因,它似乎没有检测到新下载的源代码,所以我无法设置正确的断点。
  • 是的,我在使用 Android Studio 时遇到了同样的问题。我不得不关闭并重新打开程序,然后它会显示完整的源代码,而不仅仅是方法存根。
  • 是的,我已经重新启动了几次,会尝试其他一些事情。
  • 我使用的是 2.2 版。仔细检查它是否真的正确下载/安装了源代码。你也可以试试 File --> Invalidate Caches。
  • 是的,我已经重新启动缓存并使缓存失效。最终将 Android Studio 从 2.1.x 升级到 2.2,现在可以正确读取源代码并设置断点。我已经用一些细节更新了我的问题。
【解决方案2】:

我试图从带有 BLE 芯片的牛刷刮板中读取数据。 它在 BLE 模块上处于读取特性之下。 数据以十六进制返回,即 BRUSH_OFF 为 0x00,BRUSH_ON 为 0x01

我试图在我的 android 应用程序中读取此数据,但它一直显示为空白。

问题是 0x00 = NULL in ascii 和 0x01 = SOH ascii 它不能显示在屏幕上。

0x30 = 0 in ascii 0x31 = 1 in ascii

也许你有转义字符以十六进制返回,它们无法读取。

我花了几个月的时间试图弄清楚为什么我无法读回这些值。 希望这可以帮助你。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 2014-12-26
    • 2015-06-10
    • 2015-08-26
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    相关资源
    最近更新 更多