Пример #1
0
    @Override
    public final void onConnectionStateChange(
        final BluetoothGatt gatt, final int status, final int newState) {
      Logger.d(
          mLogSession,
          "[Callback] Connection state changed with status: "
              + status
              + " and new state: "
              + newState
              + " ("
              + stateToString(newState)
              + ")");

      if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED) {
        // Notify the parent activity/service
        Logger.i(mLogSession, "Connected to " + gatt.getDevice().getAddress());
        mConnected = true;
        mCallbacks.onDeviceConnected();

        /*
         * The onConnectionStateChange event is triggered just after the Android connects to a device.
         * In case of bonded devices, the encryption is reestablished AFTER this callback is called.
         * Moreover, when the device has Service Changed indication enabled, and the list of services has changed (e.g. using the DFU),
         * the indication is received few milliseconds later, depending on the connection interval.
         * When received, Android will start performing a service discovery operation itself, internally.
         *
         * If the mBluetoothGatt.discoverServices() method would be invoked here, if would returned cached services,
         * as the SC indication wouldn't be received yet.
         * Therefore we have to postpone the service discovery operation until we are (almost, as there is no such callback) sure, that it had to be handled.
         * Our tests has shown that 600 ms is enough. It is important to call it AFTER receiving the SC indication, but not necessarily
         * after Android finishes the internal service discovery.
         *
         * NOTE: This applies only for bonded devices with Service Changed characteristic, but to be sure we will postpone
         * service discovery for all devices.
         */
        mHandler.postDelayed(
            new Runnable() {
              @Override
              public void run() {
                // Some proximity tags (e.g. nRF PROXIMITY) initialize bonding automatically when
                // connected.
                if (gatt.getDevice().getBondState() != BluetoothDevice.BOND_BONDING) {
                  Logger.v(mLogSession, "Discovering Services...");
                  Logger.d(mLogSession, "gatt.discoverServices()");
                  gatt.discoverServices();
                }
              }
            },
            600);
      } else {
        if (newState == BluetoothProfile.STATE_DISCONNECTED) {
          if (status != BluetoothGatt.GATT_SUCCESS)
            Logger.w(
                mLogSession,
                "Error: (0x"
                    + Integer.toHexString(status)
                    + "): "
                    + GattError.parseConnectionError(status));

          onDeviceDisconnected();
          mConnected = false;
          if (mUserDisconnected) {
            Logger.i(mLogSession, "Disconnected");
            mCallbacks.onDeviceDisconnected();
            close();
          } else {
            Logger.w(mLogSession, "Connection lost");
            mCallbacks.onLinklossOccur();
            // We are not closing the connection here as the device should try to reconnect
            // automatically.
            // This may be only called when the shouldAutoConnect() method returned true.
          }
          return;
        }

        // TODO Should the disconnect method be called or the connection is still valid? Does this
        // ever happen?
        Logger.e(
            mLogSession,
            "Error (0x"
                + Integer.toHexString(status)
                + "): "
                + GattError.parseConnectionError(status));
        mCallbacks.onError(ERROR_CONNECTION_STATE_CHANGE, status);
      }
    }
Пример #2
0
 private void onError(final String message, final int errorCode) {
   Logger.e(
       mLogSession,
       "Error (0x" + Integer.toHexString(errorCode) + "): " + GattError.parse(errorCode));
   mCallbacks.onError(message, errorCode);
 }