title: Bluetooth Adapter Service remaining null
body: <p>I am trying to adapt code from Bluetooth BLE developer starter kit to my own app (i.e this exact same code is working well on the example app).
  But, I can't connect to any device, because, when I am pressing the Connect button (method onConnect), bluetooth_le_adapter is null.</p>
  
  <p>I think that the bluetooth_le_adapter is not well initialized, and so, is null at startup.</p>
  
  <p>Do you have any idea on how to fix this problem ? Thanks</p>
  
  <p>PeripheralControlActivity.java:</p>
  
  <pre><code>public class PeripheralControlActivity extends Activity {
  public static final String EXTRA_NAME = "name";
  public static final String EXTRA_ID = "id";
  
  private String device_name;
  private String device_address;
  private Timer mTimer;
  private boolean sound_alarm_on_disconnect = false;
  private int alert_level;
  private boolean back_requested = false;
  private boolean share_with_server = false;
  private Switch share_switch;
  private BleAdapterService bluetooth_le_adapter;
  
  private final ServiceConnection service_connection = new ServiceConnection() {
  
      @Override
      public void onServiceConnected(ComponentName componentName, IBinder service) {
          bluetooth_le_adapter = ((BleAdapterService.LocalBinder) service).getService();
          bluetooth_le_adapter.setActivityHandler(message_handler);
      }
  
      @Override
      public void onServiceDisconnected(ComponentName componentName) {
          bluetooth_le_adapter = null;
      }
  };
  
  private Handler message_handler = new Handler() {
      @Override
      public void handleMessage(Message msg) {
          Bundle bundle;
          String service_uuid = "";
          String characteristic_uuid = "";
          byte[] b = null;
  
          switch (msg.what) {
              case BleAdapterService.MESSAGE:
                  bundle = msg.getData();
                  String text = bundle.getString(BleAdapterService.PARCEL_TEXT);
                  showMsg(text);
                  break;
              case BleAdapterService.GATT_CONNECTED:
                  ((Button) PeripheralControlActivity.this
                          .findViewById(R.id.connectButton)).setEnabled(false);
                  ((Button) PeripheralControlActivity.this.findViewById(R.id.noiseButton))
                          .setEnabled(true);
                  share_switch.setEnabled(true);
                  // we're connected
                  showMsg("CONNECTED");
                  /*AlarmManager am = AlarmManager.getInstance();
                  Log.d(Constants.TAG, "alarmIsSounding=" + am.alarmIsSounding());
                  if (am.alarmIsSounding()) {
                      Log.d(Constants.TAG, "Stopping alarm");
                      am.stopAlarm();
                  }*/
                  bluetooth_le_adapter.discoverServices();
                  break;
  
              case BleAdapterService.GATT_DISCONNECT:
                  ((Button) PeripheralControlActivity.this
                          .findViewById(R.id.connectButton)).setEnabled(true);
                  // we're disconnected
                  showMsg("DISCONNECTED");
                  // hide the rssi distance colored rectangle
                  ((LinearLayout) PeripheralControlActivity.this
                          .findViewById(R.id.rectangle))
                          .setVisibility(View.INVISIBLE);
                  share_switch.setEnabled(false);
                  // disable the LOW/MID/HIGH alert level selection buttons
                  ((Button) PeripheralControlActivity.this.findViewById(R.id.lowButton)).setEnabled(false);
                  ((Button) PeripheralControlActivity.this.findViewById(R.id.midButton)).setEnabled(false);
                  ((Button) PeripheralControlActivity.this.findViewById(R.id.highButton)).setEnabled(false);
                  // stop the rssi reading timer
                  stopTimer();
                  /*if (alert_level &gt; 0) {
                      AlarmManager.getInstance().soundAlarm(getResources().openRawResourceFd(R.raw.alarm));
                  }*/
                  if (back_requested) {
                      PeripheralControlActivity.this.finish();
                  }
                  break;
  
              case BleAdapterService.GATT_SERVICES_DISCOVERED:
  
                  // validate services and if ok....
                  List&lt;BluetoothGattService&gt; slist = bluetooth_le_adapter.getSupportedGattServices();
                  boolean link_loss_present = false;
                  boolean immediate_alert_present = false;
                  boolean tx_power_present = false;
                  boolean proximity_monitoring_present = false;
  
                  for (BluetoothGattService svc : slist) {
                      Log.d(Constants.TAG, "UUID=" + svc.getUuid().toString().toUpperCase() + " INSTANCE=" + svc.getInstanceId());
                      if (svc.getUuid().toString().equalsIgnoreCase(BleAdapterService.LINK_LOSS_SERVICE_UUID)) {
                          link_loss_present = true;
                          continue;
                      }
                      if (svc.getUuid().toString().equalsIgnoreCase(BleAdapterService.IMMEDIATE_ALERT_SERVICE_UUID)) {
                          immediate_alert_present = true;
                          continue;
                      }
                      if (svc.getUuid().toString().equalsIgnoreCase(BleAdapterService.TX_POWER_SERVICE_UUID)) {
                          tx_power_present = true;
                          continue;
                      }
                      if (svc.getUuid().toString().equalsIgnoreCase(BleAdapterService.PROXIMITY_MONITORING_SERVICE_UUID)) {
                          proximity_monitoring_present = true;
                          continue;
                      }
                  }
  
                  if (link_loss_present &amp;&amp; immediate_alert_present &amp;&amp; tx_power_present &amp;&amp; proximity_monitoring_present) {
                      showMsg("Device has expected services");
  
                      // show the rssi distance colored rectangle
                      ((LinearLayout) PeripheralControlActivity.this
                              .findViewById(R.id.rectangle))
                              .setVisibility(View.VISIBLE);
                      // enable the LOW/MID/HIGH alert level selection buttons
                      ((Button) PeripheralControlActivity.this.findViewById(R.id.lowButton)).setEnabled(true);
                      ((Button) PeripheralControlActivity.this.findViewById(R.id.midButton)).setEnabled(true);
                      ((Button) PeripheralControlActivity.this.findViewById(R.id.highButton)).setEnabled(true);
  
                      showMsg("Reading alert_level");
  
                      bluetooth_le_adapter.readCharacteristic(
                              BleAdapterService.LINK_LOSS_SERVICE_UUID,
                              BleAdapterService.ALERT_LEVEL_CHARACTERISTIC);
  
                  } else {
                      showMsg("Device does not have expected GATT services");
                  }
                  break;
  
              case BleAdapterService.GATT_REMOTE_RSSI:
                  bundle = msg.getData();
                  int rssi = bundle.getInt(BleAdapterService.PARCEL_RSSI);
                  PeripheralControlActivity.this.updateRssi(rssi);
                  break;
  
              case BleAdapterService.GATT_CHARACTERISTIC_READ:
                  bundle = msg.getData();
                  Log.d(Constants.TAG, "Service=" + bundle.get(BleAdapterService.PARCEL_SERVICE_UUID).toString().toUpperCase() + " Characteristic=" + bundle.get(BleAdapterService.PARCEL_CHARACTERISTIC_UUID).toString().toUpperCase());
                  if (bundle.get(BleAdapterService.PARCEL_CHARACTERISTIC_UUID).toString().toUpperCase()
                          .equals(BleAdapterService.ALERT_LEVEL_CHARACTERISTIC)
                          &amp;&amp; bundle.get(BleAdapterService.PARCEL_SERVICE_UUID).toString().toUpperCase()
                          .equals(BleAdapterService.LINK_LOSS_SERVICE_UUID)) {
                      b = bundle.getByteArray(BleAdapterService.PARCEL_VALUE);
                      if (b.length &gt; 0) {
                          PeripheralControlActivity.this.setAlertLevel((int) b[0]);
                          Log.d(Constants.TAG, "Current alert_level is set to: " + b[0]);
                          // show the rssi distance colored rectangle
                          ((LinearLayout) PeripheralControlActivity.this
                                  .findViewById(R.id.rectangle))
                                  .setVisibility(View.VISIBLE);
  
                          // start off the rssi reading timer
                          startReadRssiTimer();
                      }
                  }
                  break;
              case BleAdapterService.GATT_CHARACTERISTIC_WRITTEN:
                  bundle = msg.getData();
                  Log.d(Constants.TAG, "Service=" + bundle.get(BleAdapterService.PARCEL_SERVICE_UUID).toString().toUpperCase() + " Characteristic=" + bundle.get(BleAdapterService.PARCEL_CHARACTERISTIC_UUID).toString().toUpperCase());
                  if (bundle.get(BleAdapterService.PARCEL_CHARACTERISTIC_UUID).toString()
                          .toUpperCase().equals(BleAdapterService.ALERT_LEVEL_CHARACTERISTIC)
                          &amp;&amp; bundle.get(BleAdapterService.PARCEL_SERVICE_UUID).toString()
                          .toUpperCase().equals(BleAdapterService.LINK_LOSS_SERVICE_UUID)) {
                      b = bundle.getByteArray(BleAdapterService.PARCEL_VALUE);
                      Log.d(Constants.TAG, "New alert_level set to: " + b[0]);
                      PeripheralControlActivity.this.setAlertLevel((int) b[0]);
                  }
                  break;
          }
      }
  };
  
  public void onLow(View view) {
      bluetooth_le_adapter.writeCharacteristic(BleAdapterService.LINK_LOSS_SERVICE_UUID, BleAdapterService.ALERT_LEVEL_CHARACTERISTIC, Constants.ALERT_LEVEL_LOW);
  }
  
  public void onMid(View view) {
      bluetooth_le_adapter.writeCharacteristic(BleAdapterService.LINK_LOSS_SERVICE_UUID, BleAdapterService.ALERT_LEVEL_CHARACTERISTIC, Constants.ALERT_LEVEL_MID);
  }
  
  public void onHigh(View view) {
      bluetooth_le_adapter.writeCharacteristic(BleAdapterService.LINK_LOSS_SERVICE_UUID, BleAdapterService.ALERT_LEVEL_CHARACTERISTIC, Constants.ALERT_LEVEL_HIGH);
  }
  
  public void onNoise(View view) {
      byte[] al = new byte[1];
      al[0] = (byte) alert_level;
      bluetooth_le_adapter.writeCharacteristic(BleAdapterService.IMMEDIATE_ALERT_SERVICE_UUID, BleAdapterService.ALERT_LEVEL_CHARACTERISTIC, al);
  }
  
  public void onBackPressed() {
      Log.d(Constants.TAG, "onBackPressed");
      back_requested = true;
      if (bluetooth_le_adapter.isConnected()) {
          try {
              bluetooth_le_adapter.disconnect();
          } catch (Exception e) {
          }
      } else {
          finish();
      }
  }
  
  private void setAlertLevel(int alert_level) {
      this.alert_level = alert_level;
      ((Button) this.findViewById(R.id.lowButton)).setTextColor(Color.parseColor("#000000"));
      ;
      ((Button) this.findViewById(R.id.midButton)).setTextColor(Color.parseColor("#000000"));
      ;
      ((Button) this.findViewById(R.id.highButton)).setTextColor(Color.parseColor("#000000"));
      ;
      switch (alert_level) {
          case 0:
              ((Button) this.findViewById(R.id.lowButton)).setTextColor(Color.parseColor("#FF0000"));
              ;
              break;
          case 1:
              ((Button) this.findViewById(R.id.midButton)).setTextColor(Color.parseColor("#FF0000"));
              ;
              break;
          case 2:
              ((Button) this.findViewById(R.id.highButton)).setTextColor(Color.parseColor("#FF0000"));
              ;
              break;
      }
  }
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_peripheral_control);
  
      // read intent data
      final Intent intent = getIntent();
      device_name = intent.getStringExtra(EXTRA_NAME);
      device_address = intent.getStringExtra(EXTRA_ID);
  
      // show the device name
      ((TextView) this.findViewById(R.id.nameTextView)).setText("Device : " + device_name + " [" + device_address + "]");
      // hide the coloured rectangle used to show green/amber/red rssi distance
      ((LinearLayout) this.findViewById(R.id.rectangle)).setVisibility(View.INVISIBLE);
  
      // hide the coloured rectangle used to show green/amber/red rssi
      // distance
      ((LinearLayout) this.findViewById(R.id.rectangle))
              .setVisibility(View.INVISIBLE);
  
      // disable the noise button
      ((Button) PeripheralControlActivity.this.findViewById(R.id.noiseButton))
              .setEnabled(false);
  
      // disable the LOW/MID/HIGH alert level selection buttons
      ((Button) this.findViewById(R.id.lowButton)).setEnabled(false);
      ((Button) this.findViewById(R.id.midButton)).setEnabled(false);
      ((Button) this.findViewById(R.id.highButton)).setEnabled(false);
  
      share_switch = (Switch) this.findViewById(R.id.switch1);
      share_switch.setEnabled(false);
      share_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
          public void onCheckedChanged(CompoundButton buttonView,
                                       boolean isChecked) {
              if (bluetooth_le_adapter != null) {
                  share_with_server = isChecked;
                  if (!isChecked &amp;&amp; bluetooth_le_adapter.isConnected()) {
                      showMsg("Switched off sharing proximity data");
                      // write 0,0 to cause Arduino to switch off all LEDs
                      if (bluetooth_le_adapter.writeCharacteristic(
                              BleAdapterService.PROXIMITY_MONITORING_SERVICE_UUID,
                              BleAdapterService.CLIENT_PROXIMITY_CHARACTERISTIC,
                              new byte[]{0, 0})) {
                      } else {
                          showMsg("Failed to inform Arduino sharing has been disabled");
                      }
                  }
              }
          }
      });
  
      // connect to the Bluetooth adapter service
      Intent gattServiceIntent = new Intent(this, BleAdapterService.class);
      bindService(gattServiceIntent, service_connection, BIND_AUTO_CREATE);
  
      showMsg("READY");
  }
  
  @Override
  protected void onDestroy() {
      super.onDestroy();
      stopTimer();
      unbindService(service_connection);
      bluetooth_le_adapter = null;
  }
  
  private void showMsg(final String msg) {
      Log.i(Constants.TAG, msg);
      runOnUiThread(new Runnable() {
          @Override
          public void run() {
              ((TextView) findViewById(R.id.msgTextView)).setText(msg);
          }
      });
  }
  
  public void onConnect(View view) {
      showMsg("onConnect");
      if (bluetooth_le_adapter != null) {
          if (bluetooth_le_adapter.connect(device_address)) {
              ((Button) PeripheralControlActivity.this
                      .findViewById(R.id.connectButton)).setEnabled(false);
          } else {
              showMsg("onConnect: failed to connect");
          }
      } else {
          showMsg("onConnect: bluetooth_le_adapter=null");
      }
  }
  
  private void startReadRssiTimer() {
      mTimer = new Timer();
      mTimer.schedule(new TimerTask() {
          @Override
          public void run() {
              bluetooth_le_adapter.readRemoteRssi();
          }
  
      }, 0, 2000);
  }
  
  private void stopTimer() {
      if (mTimer != null) {
          mTimer.cancel();
          mTimer = null;
      }
  }
  
  private void updateRssi(int rssi) {
      ((TextView) findViewById(R.id.rssiTextView)).setText("RSSI = "
              + Integer.toString(rssi));
      LinearLayout layout = ((LinearLayout) PeripheralControlActivity.this
              .findViewById(R.id.rectangle));
  
      byte proximity_band = 3;
      if (rssi &lt; -80) {
          layout.setBackgroundColor(0xFFFF0000);
      } else if (rssi &lt; -50) {
          layout.setBackgroundColor(0xFFFF8A01);
          proximity_band = 2;
      } else {
          layout.setBackgroundColor(0xFF00FF00);
          proximity_band = 1;
      }
      layout.invalidate();
  
      if (share_with_server) {
          if (bluetooth_le_adapter.writeCharacteristic(
                  BleAdapterService.PROXIMITY_MONITORING_SERVICE_UUID,
                  BleAdapterService.CLIENT_PROXIMITY_CHARACTERISTIC,
                  new byte[]{proximity_band, (byte) rssi})) {
              showMsg("proximity data shared: proximity_band:" + proximity_band + ",rssi:" + rssi);
          } else {
              showMsg("Failed to share proximity data");
          }
      }
  
  }
  }
  </code></pre>
  
  <p>BleAdapterService.java</p>
  
  <pre><code>public class BleAdapterService extends Service {
  
  private BluetoothAdapter bluetooth_adapter;
  private BluetoothGatt bluetooth_gatt;
  private BluetoothManager bluetooth_manager;
  private Handler activity_handler = null;
  private BluetoothDevice device;
  private BluetoothGattDescriptor descriptor;
  private final IBinder binder = new LocalBinder();
  
  public boolean isConnected() {
      return connected;
  }
  
  private boolean connected = false;
  
  // messages sent back to activity
  public static final int GATT_CONNECTED = 1;
  public static final int GATT_DISCONNECT = 2;
  public static final int GATT_SERVICES_DISCOVERED = 3;
  public static final int GATT_CHARACTERISTIC_READ = 4;
  public static final int GATT_CHARACTERISTIC_WRITTEN = 5;
  public static final int GATT_REMOTE_RSSI = 6;
  public static final int MESSAGE = 7;
  
  // message params
  public static final String PARCEL_DESCRIPTOR_UUID = "DESCRIPTOR_UUID";
  public static final String PARCEL_CHARACTERISTIC_UUID = "CHARACTERISTIC_UUID";
  public static final String PARCEL_SERVICE_UUID = "SERVICE_UUID";
  public static final String PARCEL_VALUE = "VALUE";
  public static final String PARCEL_RSSI = "RSSI";
  public static final String PARCEL_TEXT = "TEXT";
  
  // service uuids
  public static String IMMEDIATE_ALERT_SERVICE_UUID = "00001802-0000-1000-8000-00805F9B34FB";
  public static String LINK_LOSS_SERVICE_UUID       = "00001803-0000-1000-8000-00805F9B34FB";
  public static String TX_POWER_SERVICE_UUID       = "00001804-0000-1000-8000-00805F9B34FB";
  public static String PROXIMITY_MONITORING_SERVICE_UUID = "3E099910-293F-11E4-93BD-AFD0FE6D1DFD";
  
  // service characteristics
  public static String ALERT_LEVEL_CHARACTERISTIC       = "00002A06-0000-1000-8000-00805F9B34FB";
  public static String CLIENT_PROXIMITY_CHARACTERISTIC = "3E099911-293F-11E4-93BD-AFD0FE6D1DFD";
  
  
  public class LocalBinder extends Binder {
      public BleAdapterService getService() {
          return BleAdapterService.this;
      }
  }
  
  @Override
  public IBinder onBind(Intent intent) {
      return binder;
  }
  
  @Override
  public boolean onUnbind(Intent intent) {
      return super.onUnbind(intent);
  }
  
  // set activity the will receive the messages
  public void setActivityHandler(Handler handler) {
      activity_handler = handler;
  }
  
  private void sendConsoleMessage(String text) {
      Message msg = Message.obtain(activity_handler, MESSAGE);
      Bundle data = new Bundle();
      data.putString(PARCEL_TEXT, text);
      msg.setData(data);
      msg.sendToTarget();
  }
  
  @Override
  public void onCreate() {
      if (bluetooth_manager == null) {
          bluetooth_manager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
          if (bluetooth_manager == null) {
              return;
          }
      }
      bluetooth_adapter = bluetooth_manager.getAdapter();
      if (bluetooth_adapter == null) {
          return;
      }
  }
  
  // connect to the device
  public boolean connect(final String address) {
  
      if (bluetooth_adapter == null || address == null) {
          sendConsoleMessage("connect: bluetooth_adapter=null");
          return false;
      }
  
      device = bluetooth_adapter.getRemoteDevice(address);
      if (device == null) {
          sendConsoleMessage("connect: device=null");
          return false;
      }
  
      bluetooth_gatt = device.connectGatt(this, false, gatt_callback);
      return true;
  }
  
  // disconnect from device
  public void disconnect() {
      sendConsoleMessage("disconnecting");
      if (bluetooth_adapter == null || bluetooth_gatt == null) {
          sendConsoleMessage("disconnect: bluetooth_adapter|bluetooth_gatt null");
          return;
      }
      if (bluetooth_gatt != null) {
          bluetooth_gatt.disconnect();
      }
  }
  
  public void readRemoteRssi() {
      if (bluetooth_adapter == null || bluetooth_gatt == null) {
          return;
      }
      bluetooth_gatt.readRemoteRssi();
  }
  
  public void discoverServices() {
      if (bluetooth_adapter == null || bluetooth_gatt == null) {
          return;
      }
      Log.d(Constants.TAG,"Discovering GATT services");
      bluetooth_gatt.discoverServices();
  }
  
  public List&lt;BluetoothGattService&gt; getSupportedGattServices() {
      if (bluetooth_gatt == null)
          return null;
      return bluetooth_gatt.getServices();
  }
  
  public boolean readCharacteristic(String serviceUuid,
                                    String characteristicUuid) {
      Log.d(Constants.TAG,"readCharacteristic:"+characteristicUuid+" of " +serviceUuid);
      if (bluetooth_adapter == null || bluetooth_gatt == null) {
          sendConsoleMessage("readCharacteristic: bluetooth_adapter|bluetooth_gatt null");
          return false;
      }
  
      BluetoothGattService gattService = bluetooth_gatt
              .getService(java.util.UUID.fromString(serviceUuid));
      if (gattService == null) {
          sendConsoleMessage("readCharacteristic: gattService null");
          return false;
      }
      BluetoothGattCharacteristic gattChar = gattService
              .getCharacteristic(java.util.UUID.fromString(characteristicUuid));
      if (gattChar == null) {
          sendConsoleMessage("readCharacteristic: gattChar null");
          return false;
      }
      return bluetooth_gatt.readCharacteristic(gattChar);
  }
  
  public boolean writeCharacteristic(String serviceUuid,
                                     String characteristicUuid, byte[] value) {
  
      Log.d(Constants.TAG,"writeCharacteristic:"+characteristicUuid+" of " +serviceUuid);
      if (bluetooth_adapter == null || bluetooth_gatt == null) {
          sendConsoleMessage("writeCharacteristic: bluetooth_adapter|bluetooth_gatt null");
          return false;
      }
  
      BluetoothGattService gattService = bluetooth_gatt
              .getService(java.util.UUID.fromString(serviceUuid));
      if (gattService == null) {
          sendConsoleMessage("writeCharacteristic: gattService null");
          return false;
      }
      BluetoothGattCharacteristic gattChar = gattService
              .getCharacteristic(java.util.UUID.fromString(characteristicUuid));
      if (gattChar == null) {
          sendConsoleMessage("writeCharacteristic: gattChar null");
          return false;
      }
      gattChar.setValue(value);
  
      return bluetooth_gatt.writeCharacteristic(gattChar);
  
  }
  
  
  private final BluetoothGattCallback gatt_callback = new BluetoothGattCallback() {
  
      @Override
      public void onConnectionStateChange(BluetoothGatt gatt, int status,
                                          int newState) {
          Log.d(Constants.TAG, "onConnectionStateChange: status=" + status);
          if (newState == BluetoothProfile.STATE_CONNECTED) {
              Log.d(Constants.TAG, "onConnectionStateChange: CONNECTED");
              connected = true;
              Message msg = Message.obtain(activity_handler, GATT_CONNECTED);
              msg.sendToTarget();
          } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
              Log.d(Constants.TAG, "onConnectionStateChange: DISCONNECTED");
              Message msg = Message.obtain(activity_handler, GATT_DISCONNECT);
              msg.sendToTarget();
              if (bluetooth_gatt != null) {
                  Log.d(Constants.TAG,"Closing and destroying BluetoothGatt object");
                  connected = false;
                  bluetooth_gatt.close();
                  bluetooth_gatt = null;
              }
          }
      }
  
      @Override
      public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
          if (status == BluetoothGatt.GATT_SUCCESS) {
              sendConsoleMessage("RSSI read OK");
              Bundle bundle = new Bundle();
              bundle.putInt(PARCEL_RSSI, rssi);
              Message msg = Message
                      .obtain(activity_handler, GATT_REMOTE_RSSI);
              msg.setData(bundle);
              msg.sendToTarget();
          } else {
              sendConsoleMessage("RSSI read err:"+status);
          }
      }
  
      @Override
      public void onServicesDiscovered(BluetoothGatt gatt, int status) {
          sendConsoleMessage("Services Discovered");
          Message msg = Message.obtain(activity_handler,
                  GATT_SERVICES_DISCOVERED);
          msg.sendToTarget();
      }
  
      @Override
      public void onCharacteristicRead(BluetoothGatt gatt,
                                       BluetoothGattCharacteristic characteristic, int status) {
          if (status == BluetoothGatt.GATT_SUCCESS) {
              Bundle bundle = new Bundle();
              bundle.putString(PARCEL_CHARACTERISTIC_UUID, characteristic.getUuid()
                      .toString());
              bundle.putString(PARCEL_SERVICE_UUID, characteristic.getService().getUuid().toString());
              bundle.putByteArray(PARCEL_VALUE, characteristic.getValue());
              Message msg = Message.obtain(activity_handler,
                      GATT_CHARACTERISTIC_READ);
              msg.setData(bundle);
              msg.sendToTarget();
          } else {
              Log.d(Constants.TAG, "failed to read characteristic:"+characteristic.getUuid().toString()+" of service "+characteristic.getService().getUuid().toString()+" : status="+status);
              sendConsoleMessage("characteristic read err:"+status);
          }
      }
  
      public void onCharacteristicWrite(BluetoothGatt gatt,
                                        BluetoothGattCharacteristic characteristic, int status) {
          Log.d(Constants.TAG, "onCharacteristicWrite");
          if (status == BluetoothGatt.GATT_SUCCESS) {
              Bundle bundle = new Bundle();
              bundle.putString(PARCEL_CHARACTERISTIC_UUID, characteristic.getUuid().toString());
              bundle.putString(PARCEL_SERVICE_UUID, characteristic.getService().getUuid().toString());
              bundle.putByteArray(PARCEL_VALUE, characteristic.getValue());
              Message msg = Message.obtain(activity_handler, GATT_CHARACTERISTIC_WRITTEN);
              msg.setData(bundle);
              msg.sendToTarget();
          } else {
              sendConsoleMessage("characteristic write err:" + status);
          }
      }
  };
  }
  </code></pre>