从BluetoothGattCharacteristic读取失败 [英] Reading from a BluetoothGattCharacteristic is failing

查看:1219
本文介绍了从BluetoothGattCharacteristic读取失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试读取存储在 BluetoothGattCharacteristic 中的值。以下是我的 BluetoothGattCallback 代码,其中大部分操作都在其中进行:

Im trying to read the value stored in a BluetoothGattCharacteristic. The following is my BluetoothGattCallback code, where most of the action takes place:

 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),表明它失败了。

So to read from the characteristic, i'm attempting to use the gatt.readCharacteristic() method, which takes a characteristic and returns a boolean indicating a successful operation or not. Here, this method is returning false (printing "res was false"), indicating it failed.

没有打印错误消息。读取特征的正确方法是什么?为什么此方法将返回 false

There is no error message being printed. What is the proper way to read a characteristic? Why would this method be returning false?

编辑:
为Inferno的建议,继续下载所需的资源,然后在 BluetoothGatt readCharacteristic()方法中设置一个断点:

As suggested by Inferno, went ahead and downloaded the needed sources and then set a breakpoint in the BluetoothGatt readCharacteristic() method:

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

Here is the readCharacteristic() method in android-23..\BluetoothGatt

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

(characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_READ) is returning 0 so false is being immediately returned. Now according to the debugger characteristic.getProperties() is returning a value of 8, while BluetoothGattCharacteristic.PROPERTY_READ has a static int value of 0x02.

据我了解, 0x08& 0x02 ==0。由于 PROPERTY_READ 是硬编码值,因此我认为特征返回的值有问题.getProperties()

As I understand, 0x08 & 0x02 == 0. Since the PROPERTY_READ is a hardcoded value, I assume something is wrong with the value returned from characteristic.getProperties(). What could be going wrong here?

推荐答案


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

What is the proper way to read a characteristic?

首先,您从内部调用 gatt.readCharacteristic(characteristic) onServicesDiscovered()回调。我看不到您的代码中存在任何严重缺陷。

First of all, you call gatt.readCharacteristic(characteristic) from inside of the onServicesDiscovered() callback, which is alright. I can't see any serious flaws in your code.

您可以在 onConnectionStateChange()中添加的内容之前之前,您还要验证 newState == BluetoothProfile.STATE_CONNECTED

What you could add in onConnectionStateChange() is an additional check before you verify newState == BluetoothProfile.STATE_CONNECTED:

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




为什么此方法返回false?

Why would this method be returning false?

我检查了 BluetoothGatt 此处事实证明,在许多不同的情况下都会返回 false 的返回值,如下面的代码所示:

I checked the android source of BluetoothGatt here and it turns out, the return value of false is returned in many different cases as you can see in the code below:

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 。这样,您将有望定位该问题。

So what I recommend you to do is, start the debugger in Android Studio and set a breakpoint inside the readCharacteristic() method (in BluetoothGatt.java) and carefully step through the code to see where false gets returned. That way you will hopefully be able to localize the issue. Besides that, anything else would be wild guessing.

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

Of course you need to have the sources downloaded to be able to view BluetoothGatt.java. But Android Studio will give you a small yellow bar at the top of the editor which asks you if you want to download and install. Just do it and restart Android Studio after the download is complete. Then you should be able to set a breakpoint in BluetoothGatt.java.

更新:


据我了解,0x08& 0x02 ==0。由于PROPERTY_READ是
硬编码值,所以我认为从attribute.getProperties()返回的
值有问题。

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

According to BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part G] page 533, the value of 0x8 which is returned by characteristic.getProperties() means, that your characteristic has write only permissions. Not a surprise that all reading attempts fail. In other words: your bluetooth device does not allow you to read that particular characteristic.

从规范中引用:

特征属性位字段决定如何使用特征值
或如何访问
特征描述符(请参见第3.3.3节)。

The Characteristic Properties bit field determines how the Characteristic Value can be used, or how the characteristic descriptors (see Section 3.3.3) can be accessed.

这篇关于从BluetoothGattCharacteristic读取失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆