2016-09-28 428 views
1

我试图读取存储在BluetoothGattCharacteristic中的值。以下是我的BluetoothGattCallback代码,其中大部分动作发生:从BluetoothGattCharacteristic读取失败

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

编辑: 如地狱建议,说干就干,下载所需要的资源,然后在BluetoothGattreadCharacteristic()方法设置断点:

这里采用的是Android-23的readCharacteristic()方法.. \ 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

据我所知,0x08 & 0x02 == 0.由于PROPERTY_READ是硬编码值,我假设从characteristic.getProperties()返回的值有问题。这里可能会出现什么问题?

+0

即使'gatt.readCharacteristic()'返回'false',回调'onCharacteristicRead()'也会发生吗? –

+0

不,它不会被调用。 – Orbit

+0

我会更新我的答案,给我第二个 –

回答

2

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

首先,你从onServicesDiscovered()回调里面调用gatt.readCharacteristic(characteristic),这是没问题的。我看不到你的代码有任何严重的缺陷。

什么,你可以在onConnectionStateChange()添加一个额外的检查验证之前newState == BluetoothProfile.STATE_CONNECTED

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

为什么这种方法返回false?

我检查的BluetoothGatthere了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中设置一个断点。

UPDATE:

据我了解,0x08的& 0×02 == 0,由于PROPERTY_READ是 硬编码值,我认为事情是错误的值从characteristic.getProperties返回 ()。这里可能会出现什么问题?

根据蓝牙规范版本4.2 [第3卷,部分G] 533页,其通过characteristic.getProperties()装置返回,您的特性具有只写权限的0x8值。毫不奇怪,所有阅读尝试都失败了。换句话说:您的蓝牙设备不允许您阅读特定的特性。从说明书

引用:

特征性质的位字段决定如何特征值 可以使用,或如何的特征描述符(见第3.3.3节)可以是 访问。

+0

我打开'readCharacteristic()'方法并下载源代码,但由于某种奇怪的原因,它似乎没有检测到新下载的源代码,所以我无法设置合适的断点。 – Orbit

+0

是的,我有与Android Studio相同的问题。我不得不关闭并重新打开该程序,然后显示完整的源代码而不是方法存根。 –

+0

是的,我已经重新启动了几次,会尝试一些其他的事情。 – Orbit

0

我正试图从一个有刷BLE芯片的牛刷子抓取数据。 它在BLE模块的读取特性下。 数据回来了十六进制,即0x00作为BRUSH_OFF &为0×01 BRUSH_ON

我试图在这一数据在我的Android应用程序读取,并保持回来为空白。

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

的0x30 = 0 ASCII 0X31 = 1 ASCII

也许你有转义字符回来十六进制,它们不能被读取。

我花了几个月试图找出为什么我不能读回值。 希望这可能会帮助你。