@Override
  public void onReceive(Context context, Intent intent) {
    Options options = null;
    Bundle bundle = intent.getExtras();
    JSONObject args;

    try {
      args = new JSONObject(bundle.getString(OPTIONS));
      options = new Options(context).parse(args);
    } catch (JSONException e) {
      return;
    }

    this.context = context;
    this.options = options;

    // The context may got lost if the app was not running before
    LocalNotification.setContext(context);

    fireTriggerEvent();

    if (options.getInterval() == 0) {
      LocalNotification.unpersist(options.getId());
    } else if (isFirstAlarmInFuture()) {
      return;
    } else {
      LocalNotification.add(options.moveDate(), false);
    }

    Builder notification = buildNotification();

    showNotification(notification);
  }
  /**
   * Set an alarm.
   *
   * @param options The options that can be specified per alarm.
   */
  public static void add(Options options) {
    long triggerTime = options.getDate();

    Intent intent =
        new Intent(context, Receiver.class)
            .setAction("" + options.getId())
            .putExtra(Receiver.OPTIONS, options.getJSONObject().toString());

    AlarmManager am = getAlarmManager();
    PendingIntent pi =
        PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);

    if (options.getInterval() > 0) {
      am.setRepeating(AlarmManager.RTC_WAKEUP, triggerTime, options.getInterval(), pi);
    } else {
      am.set(AlarmManager.RTC_WAKEUP, triggerTime, pi);
    }
  }
  /*
   * If you set a repeating alarm at 11:00 in the morning and it
   * should trigger every morning at 08:00 o'clock, it will
   * immediately fire. E.g. Android tries to make up for the
   * 'forgotten' reminder for that day. Therefore we ignore the event
   * if Android tries to 'catch up'.
   */
  private Boolean isFirstAlarmInFuture() {
    if (options.getInterval() > 0) {
      Calendar now = Calendar.getInstance();
      Calendar alarm = options.getCalendar();

      int alarmHour = alarm.get(Calendar.HOUR_OF_DAY);
      int alarmMin = alarm.get(Calendar.MINUTE);
      int currentHour = now.get(Calendar.HOUR_OF_DAY);
      int currentMin = now.get(Calendar.MINUTE);

      if (currentHour != alarmHour && currentMin != alarmMin) {
        return true;
      }
    }

    return false;
  }