Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/178.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 从一个蓝牙人身上阅读特征是失败的_Android_Bluetooth Lowenergy_Android Bluetooth_Android Ble - Fatal编程技术网

Android 从一个蓝牙人身上阅读特征是失败的

Android 从一个蓝牙人身上阅读特征是失败的,android,bluetooth-lowenergy,android-bluetooth,android-ble,Android,Bluetooth Lowenergy,Android Bluetooth,Android Ble,我正在尝试读取存储在BluetoothGattCharacteristic中的值。以下是我的BluetoothGattCallback代码,其中大部分操作发生: private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateCha

我正在尝试读取存储在
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中的
readCharacteristic()
方法

public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) {
        if ((characteristic.getProperties() &
                BluetoothGattCharacteristic.PROPERTY_READ) == 0) return false;
(characteristic.getProperties()&BluetoothGattCharacteristic.PROPERTY\u READ)
返回0,因此
false
立即返回。现在,根据调试器的
特性,getProperties()
返回的值为
8
,而
BluetoothGattCharacteristic.PROPERTY\u READ
的静态int值为
0x02

据我所知,
0x08&0x02
==0。由于
属性\u READ
是一个硬编码的值,因此我假设从
characteristic.getProperties()
返回的值有问题。这里会出什么问题

阅读特征的正确方式是什么

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

在验证
newState==BluetoothProfile.STATE\u CONNECTED
之前,可以在
onConnectionStateChange()
中添加额外的检查:

if (status == BluetoothGatt.GATT_SUCCESS) { ...
为什么这个方法会返回false

我检查了
BluetoothGatt
的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。因为属性_READ是一个 硬编码值,我假设返回的值有问题 来自characteristic.getProperties()。这里会出什么问题

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

从规范中引用:

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


我当时正试图从一个有可编程芯片的奶牛刷子刮擦器中读取数据。 它在可编程模块上具有读取特性。 数据以十六进制返回,即0x00表示刷合,0x01表示刷合

我试着在我的android应用程序中读取这些数据,但结果总是显示为空白

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

ascii中的0x30=0 ascii中的0x31=1

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

我花了几个月的时间试图弄明白为什么我不能读回这些值。
希望这能对你有所帮助

回调
onCharacteristicRead()
是否在
gatt.readCharacteristic()
返回
false
时发生?不,它不会被调用。我会更新我的答案,给我一秒钟我打开了
readCharacteristic()
方法并下载了源代码,但出于某种奇怪的原因,它似乎没有检测到新下载的源代码,因此我无法设置正确的断点。是的,我在Android Studio上也遇到了同样的问题。我不得不关闭并重新打开程序,然后它显示了完整的源代码,而不是只显示方法存根。是的,我已经重新启动了几次,将尝试其他一些事情。我使用的是2.2版。仔细检查它是否真的正确下载/安装了源代码。您也可以尝试文件-->使缓存无效。是的,我已重新启动并使缓存无效。最终将AndroidStudio从2.1.x升级到2.2,现在可以正确读取源代码并设置断点。我已经用一些细节更新了我的问题。