2014-12-03 39 views
0

我正在寫一些代碼來獲得TI Keyfob(cc2540)加速器數據。 應該啓用3個特徵通知。 我將它們一一設置並啓用了BluetoothGattDescriptor,但在代碼運行後,只有第一個BluetoothGattDescriptor可以發送通知。如何在Android 4.3中啓用多個BluetoothGattDescriptor?

我的設備是Samsung S3和Android 4.3。

下面是我的一些BluetoothService.java代碼:

static final byte[] DISABLE = {0x00}; 
static final byte[] ENABLE = {0x01}; 

public void enableKeyfobAccelService(boolean enable) { 
    BluetoothGattService _service = mBluetoothGatt.getService(UUID_KEYFOB_ACCEL_SERVICE); 
    if (_service == null) { 
     Log.d(TAG, "Keyfob Accel service not found!"); 
     return; 
    } 

    Log.d(TAG, "Keyfob Accel service found!"); 

    // write value to Characteristic ACCEL_ENABLER "0000ffa1-0000-1000-8000-00805f9b34fb" 
    BluetoothGattCharacteristic _nc = _service.getCharacteristic(UUID_KEYFOB_ACCEL_ENABLER); 
    if (_nc != null) { 
     if (enable) 
      _nc.setValue(ENABLE); 
     else 
      _nc.setValue(DISABLE); 
     mBluetoothGatt.writeCharacteristic(_nc); 
    } 

    accel_enabled = enable; 
} 


// Implements callback methods for GATT events that the app cares about. For 
// example, 
// connection change and services discovered. 
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { 
    @Override 
    public void onConnectionStateChange(BluetoothGatt gatt, int status, 
             int newState) { 
     String intentAction; 
     if (newState == BluetoothProfile.STATE_CONNECTED) { 
      intentAction = ACTION_GATT_CONNECTED; 
      mConnectionState = STATE_CONNECTED; 
      broadcastUpdate(intentAction); 
      Log.i(TAG, "Connected to GATT server."); 
      // Attempts to discover services after successful connection. 
      Log.i(TAG, "Attempting to start service discovery:" 
        + mBluetoothGatt.discoverServices()); 

     } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { 
      intentAction = ACTION_GATT_DISCONNECTED; 
      mConnectionState = STATE_DISCONNECTED; 
      Log.i(TAG, "Disconnected from GATT server."); 
      broadcastUpdate(intentAction); 
     } 
    } 

    @Override 
    public void onServicesDiscovered(BluetoothGatt gatt, int status) { 
     if (status == BluetoothGatt.GATT_SUCCESS) { 
      broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); 
     } else { 
      Log.w(TAG, "onServicesDiscovered received: " + status); 
     } 
    } 

    @Override 
    public void onCharacteristicRead(BluetoothGatt gatt, 
            BluetoothGattCharacteristic characteristic, int status) { 
     if (status == BluetoothGatt.GATT_SUCCESS) { 
      broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); 
     } 
    } 

    @Override 
    public void onCharacteristicWrite(BluetoothGatt gatt, 
             BluetoothGattCharacteristic characteristic, int status) { 
     if (status == BluetoothGatt.GATT_SUCCESS) { 

      Log.v(TAG, "onCharacteristicWrite value : " + byteArrayToHex(characteristic.getValue())); 

      if (UUID_KEYFOB_ACCEL_ENABLER.equals(characteristic.getUuid())) { 

       BluetoothGattCharacteristic _nc = characteristic.getService().getCharacteristic(UUID_KEYFOB_ACCEL_X); 

       if(_nc != null) { 
        setCharacteristicNotification(_nc, accel_enabled); 
        Log.d(TAG, "Keyfob Accel X ready! " + accel_enabled); 
       } 
       else { 
        Log.d(TAG, "Keyfob Accel UUID_KEYFOB_ACCEL_X is null! "); 
       } 

       _nc = characteristic.getService().getCharacteristic(UUID_KEYFOB_ACCEL_Y); 

       if(_nc != null) { 
        setCharacteristicNotification(_nc, accel_enabled); 
        Log.d(TAG, "Keyfob Accel Y ready! " + accel_enabled); 
       } 
       else { 
        Log.d(TAG, "Keyfob Accel UUID_KEYFOB_ACCEL_Y is null! "); 
       } 

       _nc = characteristic.getService().getCharacteristic(UUID_KEYFOB_ACCEL_Z); 

       if(_nc != null) { 
        setCharacteristicNotification(_nc, accel_enabled); 
        Log.d(TAG, "Keyfob Accel Z ready! " + accel_enabled); 
       } 
       else { 
        Log.d(TAG, "Keyfob Accel UUID_KEYFOB_ACCEL_Z is null! "); 
       } 
      } 
     } 
    } 

    @Override 
    public void onCharacteristicChanged(BluetoothGatt gatt, 
             BluetoothGattCharacteristic characteristic) { 
     broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); 
    } 
}; 

public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) { 
    if (mBluetoothAdapter == null || mBluetoothGatt == null) { 
     Log.w(TAG, "BluetoothAdapter not initialized"); 
     return; 
    } 

    if (characteristic == null) { 
     Log.w(TAG, "Bluetooth characteristic not initialized"); 
     return; 
    } 

    boolean success = mBluetoothGatt.setCharacteristicNotification(characteristic, enabled); 
    Log.v(TAG, "setCharacteristicNotification = " + success); 

    BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG)); 
    if (descriptor != null) { 
     byte[] val = enabled ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE; 
     descriptor.setValue(val); 
     mBluetoothGatt.writeDescriptor(descriptor); 
    } 
} 

我enbaled的UUID_KEYFOB_ACCEL_ENABLER後,我可以讀取日誌就知道這三個mBluetoothGatt.writeDescriptor(描述)都拼命地跑。但onCharacteristicChanged()只能從UUID_KEYFOB_ACCEL_X中獲取已更改的值。

這很奇怪,並尋求你的幫助。

非常感謝。

回答

0

我發現這個伊蘇斯的原因:對BLE,應該等待兩個寫之間的一些時間:

_nc = characteristic.getService().getCharacteristic(UUID_KEYFOB_ACCEL_Y); 

if(_nc != null) { 
    setCharacteristicNotification(_nc, accel_enabled); 
    Log.d(TAG, "Keyfob Accel Y ready! " + accel_enabled); 
} 
else { 
    Log.d(TAG, "Keyfob Accel UUID_KEYFOB_ACCEL_Y is null! "); 
} 

// MUST add wait some times 
try { 
     Thread.sleep(100); 
    } catch (Exception e) { 
     // ignore 
    } 

_nc = characteristic.getService().getCharacteristic(UUID_KEYFOB_ACCEL_Z); 

if(_nc != null) { 
    setCharacteristicNotification(_nc, accel_enabled); 
    Log.d(TAG, "Keyfob Accel Z ready! " + accel_enabled); 
} 
else { 
    Log.d(TAG, "Keyfob Accel UUID_KEYFOB_ACCEL_Z is null! "); 
} 
相關問題