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,现在可以正确读取源代码并设置断点。我已经用一些细节更新了我的问题。