2017-02-02 77 views
0

我已經按照在https://developer.android.com/samples/BluetoothLeGatt/src/com.example.android.bluetoothlegatt/DeviceScanActivity.htmlAndroid的藍牙onCharacteristicChanged從來沒有所謂

列出的導遊,我無法弄清楚如何觸發一個通知特徵值變化時。 onCharacteristicChanged方法永遠不會被調用,但我知道這個值每2秒就會改變一次。我通過在發現服務時調用readCharacteristic並在之後反覆出現,來解決這個問題。我不相信這是正確的方法,而只是在onCharacteristicChanged方法發送廣播時才應該閱讀。是否有可能通知工作或這是最好的方法?

設備控制器:

public class WarningActivity extends AppCompatActivity { 
    private static final String TAG = "WarningActivity Class"; 
    private BluetoothLeService mBluetoothLeService; 
    public static WarningActivity wInstance; 
    private boolean mConnected = false; 
    private String mDeviceAddress; 
    private boolean quitService; 
    private TextView connectStatus; 
    private Button connectButton; 
    private Button cameraButton; 
    private BluetoothManager mBluetoothManager; 
    private Vibrator vib; 
    private Uri notification; 
    private Ringtone ring; 

    private final ServiceConnection mServiceConnection = new ServiceConnection() { 
     @Override 
     public void onServiceConnected(ComponentName componentName, IBinder service) { 
      mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService(); 
      if (!mBluetoothLeService.initialize()) { 
       Log.e(TAG, "Unable to initialize Bluetooth"); 
       finish(); 
      } 
      mBluetoothLeService.connect(mDeviceAddress); 

     } 

     @Override 
     public void onServiceDisconnected(ComponentName componentName) { 
      mBluetoothLeService = null; 
     } 
    }; 

    private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      final String action = intent.getAction(); 

      if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) { 
       mConnected = true; 

      } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) { 
       mConnected = false; 

      } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) { 
       Log.i("Data: ", mBluetoothLeService.getSupportedGattService().toString()); 
       BluetoothGattService mService = mBluetoothLeService.getSupportedGattService(); 
       BluetoothGattCharacteristic characteristic = mService.getCharacteristic(mBluetoothLeService.ALERT_UUID); 
       mBluetoothLeService.setCharacteristicNotification(characteristic, true); 
       mBluetoothLeService.readCharacteristic(characteristic); 

      } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { 
       BluetoothGattService mService = mBluetoothLeService.getSupportedGattService(); 
       BluetoothGattCharacteristic characteristic = mService.getCharacteristic(mBluetoothLeService.ALERT_UUID); 
       byte[] temp = intent.getByteArrayExtra(BluetoothLeService.EXTRA_DATA); 
       String tempString = Arrays.toString(temp); 
       Log.i("Data: ", Arrays.toString(temp)); 
       mBluetoothLeService.readCharacteristic(characteristic); 
      } 
     } 
    }; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     ColorDrawable colorDrawable = new ColorDrawable(Color.parseColor("#268011")); 
     getSupportActionBar().setBackgroundDrawable(colorDrawable); 
     this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED); 

     connectButton = (Button) findViewById(R.id.connectButton); 
     connectButton.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.connected_logo, 0, 0); 
     connectButton.setClickable(false); 

     Intent gattServiceIntent = new Intent(this, BluetoothLeService.class); 
     bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE); 

     Intent intent = getIntent(); 
     mDeviceAddress = intent.getStringExtra("EXTRA_DEVICE_ADDRESS"); 

     mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); 
     vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 
     notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); 
     ring = RingtoneManager.getRingtone(getApplicationContext(), notification); 
     wInstance = this; 

     quitService = false; 

     connectStatus = (TextView) findViewById(R.id.connectMessage); 
     connectStatus.setText("Connected to: \n " + mDeviceAddress); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter()); 
     if (mBluetoothLeService != null) { 
      final boolean result = mBluetoothLeService.connect(mDeviceAddress); 
      Log.d(TAG, "Connect request result=" + result); 
     } 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     unregisterReceiver(mGattUpdateReceiver); 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     unbindService(mServiceConnection); 
     mBluetoothLeService = null; 
    } 

    private static IntentFilter makeGattUpdateIntentFilter() { 
     final IntentFilter intentFilter = new IntentFilter(); 
     intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED); 
     intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED); 
     intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED); 
     intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE); 
     return intentFilter; 
    } 
} 

BluetoothLeService

public class BluetoothLeService extends Service { 
    private final static String TAG = BluetoothLeService.class.getSimpleName(); 

    private BluetoothManager mBluetoothManager; 
    private BluetoothAdapter mBluetoothAdapter; 
    private String mBluetoothDeviceAddress; 
    private BluetoothGatt mBluetoothGatt; 
    private int mConnectionState = STATE_DISCONNECTED; 

    private static final int STATE_DISCONNECTED = 0; 
    private static final int STATE_CONNECTING = 1; 
    private static final int STATE_CONNECTED = 2; 

    public final static String ACTION_GATT_CONNECTED = "ACTION_GATT_CONNECTED"; 
    public final static String ACTION_GATT_DISCONNECTED = "ACTION_GATT_DISCONNECTED"; 
    public final static String ACTION_GATT_SERVICES_DISCOVERED = "ACTION_GATT_SERVICES_DISCOVERED"; 
    public final static String ACTION_DATA_AVAILABLE = "ACTION_DATA_AVAILABLE"; 
    public final static String EXTRA_DATA = "EXTRA_DATA"; 

    public final static UUID SERVICE_UUID = UUID.fromString(GattAttributes.BLE_SERVICE); 
    public final static UUID ALERT_UUID = UUID.fromString(GattAttributes.BLE_ALERT_CHARACTERISTIC); 

    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."); 
       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) { 
      Log.i("BlueToothService: ", "onCharacteristicRead " + characteristic.toString()); 
      if (status == BluetoothGatt.GATT_SUCCESS) { 
       broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); 
      } 
     } 

     @Override 
     public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { 
      Log.i("BlueToothService: ", "onCharacteristicChanged " + characteristic.toString()); 
      broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); 
     } 
    }; 

    private void broadcastUpdate(final String action) { 
     final Intent intent = new Intent(action); 
     Log.i("BlueToothService: ", "BroadcastUpdate ActionOnly: " + action); 
     sendBroadcast(intent); 
    } 

    private void broadcastUpdate(final String action, final BluetoothGattCharacteristic characteristic) { 
     final Intent intent = new Intent(action); 
     Log.i("BlueToothService: ", "BroadcastUpdateLong " + characteristic.toString() + " Action:" + action); 

     intent.putExtra(EXTRA_DATA, characteristic.getValue()); 
     sendBroadcast(intent); 
    } 

    public class LocalBinder extends Binder { 
     BluetoothLeService getService() { 
      return BluetoothLeService.this; 
     } 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return mBinder; 
    } 

    @Override 
    public boolean onUnbind(Intent intent) { 
     close(); 
     return super.onUnbind(intent); 
    } 

    private final IBinder mBinder = new LocalBinder(); 

    public boolean initialize() { 
     // For API level 18 and above, get a reference to BluetoothAdapter through 
     if (mBluetoothManager == null) { 
      mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); 
      if (mBluetoothManager == null) { 
       Log.e(TAG, "Unable to initialize BluetoothManager."); 
       return false; 
      } 
     } 

     mBluetoothAdapter = mBluetoothManager.getAdapter(); 
     if (mBluetoothAdapter == null) { 
      Log.e(TAG, "Unable to obtain a BluetoothAdapter."); 
      return false; 
     } 

     return true; 
    } 

    public boolean connect(final String address) { 
     if (mBluetoothAdapter == null || address == null) { 
      Log.w(TAG, "BluetoothAdapter not initialized or unspecified address."); 
      return false; 
     } 

     if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress) && mBluetoothGatt != null) { 
      Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection."); 
      if (mBluetoothGatt.connect()) { 
       mConnectionState = STATE_CONNECTING; 
       return true; 
      } else { 
       return false; 
      } 
     } 

     final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); 
     if (device == null) { 
      Log.w(TAG, "Device not found. Unable to connect."); 
      return false; 
     } 

     mBluetoothGatt = device.connectGatt(this, false, mGattCallback); 
     Log.d(TAG, "Trying to create a new connection."); 
     mBluetoothDeviceAddress = address; 
     mConnectionState = STATE_CONNECTING; 
     return true; 
    } 

    public void disconnect() { 
     if (mBluetoothAdapter == null || mBluetoothGatt == null) { 
      Log.w(TAG, "BluetoothAdapter not initialized"); 
      return; 
     } 
     mBluetoothGatt.disconnect(); 
    } 

    public void close() { 
     if (mBluetoothGatt == null) { 
      return; 
     } 
     mBluetoothGatt.close(); 
     mBluetoothGatt = null; 
    } 

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

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

     mBluetoothGatt.setCharacteristicNotification(characteristic, enabled); 
     if (SERVICE_UUID.equals(characteristic.getUuid())) { 
      BluetoothGattDescriptor descriptor = characteristic.getDescriptor(ALERT_UUID); 
      descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); 
      mBluetoothGatt.writeDescriptor(descriptor); 
     } 
    } 

    public BluetoothGattService getSupportedGattService() { 
     if (mBluetoothGatt == null) return null; 

     return mBluetoothGatt.getService(SERVICE_UUID); 
    } 
} 

回答

1

發現的解決方案:鍵入錯誤的經典案例和錯誤的描述UUID。我在哪裏找到答案BLE GATT onCharacteristicChanged not called after subscribing to notification。該錯誤類型是在setCharacteristicNotification方法中。更改爲ALERT_UUID,以及哪篇文章假設了正確的描述符UUID

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

    mBluetoothGatt.setCharacteristicNotification(characteristic, enabled); 
    if (ALERT_UUID.equals(characteristic.getUuid())) { 
     BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")); 
     descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); 
     mBluetoothGatt.writeDescriptor(descriptor); 
    } 
} 
相關問題