从BluetoothGattCharacteristic读取失败

时间:2016-09-28 01:02:08

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

我试图读取存储在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为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()返回的值有问题。这里可能出现什么问题?

2 个答案:

答案 0 :(得分:2)

  

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

首先,你从gatt.readCharacteristic(characteristic)回调中调用onServicesDiscovered(),这是好的。我无法在您的代码中看到任何严重缺陷。

您可以在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是a   硬编码值,我假设返回的值有问题   来自characteristic.getProperties()。这里可能出现什么问题?

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

引自规范:

  

特性属性位字段确定特征值的方式   可以使用,或者特征描述符(见3.3.3节)可以如何使用   访问。

答案 1 :(得分:0)

我试图从具有BLE芯片的牛刷刮读数据。 它在BLE模块上具有读取特性。 数据以十六进制返回,即BRUSH_OFF&的0x00。 BRUSH_ON的0x01

我试图在我的Android应用程序中读取此数据并且它一直空白。

问题是0x00 = ascii中的NUll和0x01 = SOH ascii它无法在屏幕上显示。

0x30 = 0 ascii 0x31 = 1 in ascii

也许你的转义字符以十六进制形式返回,无法读取。

我花了几个月试图找出为什么我无法回读这些价值观。 希望这可能对你有所帮助。