2016-09-28 246 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

也許你有轉義字符回來十六進制,它們不能被讀取。

我花了幾個月試圖找出爲什麼我不能讀回值。 希望這可能會幫助你。