@Override
        public void onCharacteristicNotified(
            BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
          final UUID uuid = characteristic.getUuid();

          if (GM_CHARACTERISTIC.equals(uuid)) {
            if (mLogSession != null)
              Logger.a(mLogSession, GlucoseMeasurementParser.parse(characteristic));

            int offset = 0;
            final int flags =
                characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, offset);
            offset += 1;

            final boolean timeOffsetPresent = (flags & 0x01) > 0;
            final boolean typeAndLocationPresent = (flags & 0x02) > 0;
            final int concentrationUnit =
                (flags & 0x04) > 0 ? GlucoseRecord.UNIT_molpl : GlucoseRecord.UNIT_kgpl;
            final boolean sensorStatusAnnunciationPresent = (flags & 0x08) > 0;
            final boolean contextInfoFollows = (flags & 0x10) > 0;

            // create and fill the new record
            final GlucoseRecord record = new GlucoseRecord();
            record.sequenceNumber =
                characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, offset);
            offset += 2;

            final int year =
                characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, offset);
            final int month =
                characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, offset + 2)
                    - 1; // months are 1-based
            final int day =
                characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, offset + 3);
            final int hours =
                characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, offset + 4);
            final int minutes =
                characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, offset + 5);
            final int seconds =
                characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, offset + 6);
            offset += 7;

            final Calendar calendar = Calendar.getInstance();
            calendar.set(year, month, day, hours, minutes, seconds);
            record.time = calendar;

            if (timeOffsetPresent) {
              // time offset is ignored in the current release
              record.timeOffset =
                  characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_SINT16, offset);
              offset += 2;
            }

            if (typeAndLocationPresent) {
              record.glucoseConcentration =
                  characteristic.getFloatValue(BluetoothGattCharacteristic.FORMAT_SFLOAT, offset);
              record.unit = concentrationUnit;
              final int typeAndLocation =
                  characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, offset + 2);
              record.type = (typeAndLocation & 0xF0) >> 4; // TODO this way or around?
              record.sampleLocation = (typeAndLocation & 0x0F);
              offset += 3;
            }

            if (sensorStatusAnnunciationPresent) {
              record.status =
                  characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, offset);
            }
            // This allows you to check other values that are not provided by the Nordic
            // Semiconductor's Glucose Service in SDK 4.4.2.
            //				record.status = 0x1A;
            //				record.context = new GlucoseRecord.MeasurementContext();
            //				record.context.carbohydrateId = 1;
            //				record.context.carbohydrateUnits = 0.23f;
            //				record.context.meal = 2;
            //				record.context.tester = 2;
            //				record.context.health = 4;
            // the following values are not implemented yet (see
            // ExpandableRecordAdapter#getChildrenCount() and #getChild(...)
            //				record.context.exerciseDuration = 3600;
            //				record.context.exerciseIntensity = 45;
            //				record.context.medicationId = 3;
            //				record.context.medicationQuantity = 0.03f;
            //				record.context.medicationUnit = GlucoseRecord.MeasurementContext.UNIT_kg;
            //				record.context.HbA1c = 213.3f;

            // data set modifications must be done in UI thread
            mHandler.post(
                new Runnable() {
                  @Override
                  public void run() {
                    // insert the new record to storage
                    mRecords.put(record.sequenceNumber, record);

                    // if there is no context information following the measurement data, notify
                    // callback about the new record
                    if (!contextInfoFollows) mCallbacks.onDatasetChanged();
                  }
                });
          } else if (GM_CONTEXT_CHARACTERISTIC.equals(uuid)) {
            if (mLogSession != null)
              Logger.a(mLogSession, GlucoseMeasurementContextParser.parse(characteristic));

            int offset = 0;
            final int flags =
                characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, offset);
            offset += 1;

            final boolean carbohydratePresent = (flags & 0x01) > 0;
            final boolean mealPresent = (flags & 0x02) > 0;
            final boolean testerHealthPresent = (flags & 0x04) > 0;
            final boolean exercisePresent = (flags & 0x08) > 0;
            final boolean medicationPresent = (flags & 0x10) > 0;
            final int medicationUnit =
                (flags & 0x20) > 0
                    ? GlucoseRecord.MeasurementContext.UNIT_l
                    : GlucoseRecord.MeasurementContext.UNIT_kg;
            final boolean hbA1cPresent = (flags & 0x40) > 0;
            final boolean moreFlagsPresent = (flags & 0x80) > 0;

            final int sequenceNumber =
                characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, offset);
            offset += 2;

            final GlucoseRecord record = mRecords.get(sequenceNumber);
            if (record == null) {
              DebugLogger.w(
                  TAG, "Context information with unknown sequence number: " + sequenceNumber);
              return;
            }

            final GlucoseRecord.MeasurementContext context = new GlucoseRecord.MeasurementContext();
            record.context = context;

            if (moreFlagsPresent) offset += 1;

            if (carbohydratePresent) {
              context.carbohydrateId =
                  characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, offset);
              context.carbohydrateUnits =
                  characteristic.getFloatValue(
                      BluetoothGattCharacteristic.FORMAT_SFLOAT, offset + 1);
              offset += 3;
            }

            if (mealPresent) {
              context.meal =
                  characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, offset);
              offset += 1;
            }

            if (testerHealthPresent) {
              final int testerHealth =
                  characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, offset);
              context.tester = (testerHealth & 0xF0) >> 4;
              context.health = (testerHealth & 0x0F);
              offset += 1;
            }

            if (exercisePresent) {
              context.exerciseDuration =
                  characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, offset);
              context.exerciseIntensity =
                  characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, offset + 2);
              offset += 3;
            }

            if (medicationPresent) {
              context.medicationId =
                  characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, offset);
              context.medicationQuantity =
                  characteristic.getFloatValue(
                      BluetoothGattCharacteristic.FORMAT_SFLOAT, offset + 1);
              context.medicationUnit = medicationUnit;
              offset += 3;
            }

            if (hbA1cPresent) {
              context.HbA1c =
                  characteristic.getFloatValue(BluetoothGattCharacteristic.FORMAT_SFLOAT, offset);
            }

            // notify callback about the new record
            mCallbacks.onDatasetChanged();
          }
        }