title: Android Alarm Manager Set Repeating at Specific Timing
body: <p>I am having some problem with alarm manager in Android. So what I am trying to do is set the alarm to repeat to run the DB insertion every day around 12.01AM.</p>
  
  <pre><code>Calendar calendar = Calendar.getInstance();
      calendar.setTimeInMillis(System.currentTimeMillis());
      calendar.set(Calendar.HOUR_OF_DAY, 0 );
      calendar.set(Calendar.MINUTE, 1);
          notificationCount = notificationCount + 1;
          AlarmManager mgr = (AlarmManager) context
                  .getSystemService(Context.ALARM_SERVICE);
          Intent notificationIntent = new Intent(context,
                  ReminderAlarm.class);
  
          notificationIntent.putExtra("NotifyCount", notificationCount);
          PendingIntent pi = PendingIntent.getBroadcast(context,
                  notificationCount, notificationIntent,
                  PendingIntent.FLAG_UPDATE_CURRENT);
          mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
                  calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
  </code></pre>
  
  <p>So basically I've came up with these code. However, the alarm manager execute again after the minute I set it. </p>
  
  <p>Let's say I run the apps on 01/10/2014 5.48PM. I wanted this to run the DB insertion when onReceive every day after I set it around 12.01AM only. But somehow, the alarm manager execute at 01/10/2014 5.49PM which is one minute after I set it and it stopped working. </p>
  
  <p>I wonder which part I did wrongly.</p>
  
  <p>Thanks in advance.</p>
  
  <p><strong>EDIT</strong>    </p>
  
  <p><strong>Recurring class</strong>
  For this class, it will trigger the alarm manager everyday and pass the variables along to reminder alarm class for DB insertion.</p>
  
  <pre><code>protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.recurring);
      context = this;
      buildListView();
      if(!alarmInitialized(this)) { 
          scheduleAlarms(this); 
      }
  }
  
  // And the few methods you suggested to schedule the alarm
  public static void scheduleAlarms(Context context) {
      Calendar calendar = Calendar.getInstance();
      if (hasRunnedToday(context)) { // if the alarm has run this day
          calendar.add(Calendar.DATE, 1); // schedule it to run again starting
                                          // tomorrow
      }
  
      long firstRunTime = calendar.getTimeInMillis();
      AlarmManager mgr = (AlarmManager) context
              .getSystemService(Context.ALARM_SERVICE);
      Intent notificationIntent = new Intent(context, ReminderAlarm.class);
      PendingIntent pi = PendingIntent.getActivity(context, 0,
              notificationIntent, 0);
      mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstRunTime,
              AlarmManager.INTERVAL_DAY, pi);
  
      ComponentName receiver = new ComponentName(context, BootReceiver.class);
      PackageManager pm = context.getPackageManager();
  
      pm.setComponentEnabledSetting(receiver,
              PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
              PackageManager.DONT_KILL_APP);
  }
  </code></pre>
  
  <p><strong>BootReceiver class</strong></p>
  
  <pre><code>public void onReceive(Context context, Intent i) {
      if (i.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
          Recurring.scheduleAlarms(context);
      }
  }
  </code></pre>
  
  <p><strong>ReminderAlarm class</strong>
  Basically for this class it just grab the variable passed from Recurring class and execute the DB insertion. I did inserted some Toast.makeText to test if it is retrieving but no luck by testing it.</p>
  
  <pre><code>public class ReminderAlarm extends BroadcastReceiver {
  private NotificationManager mNotificationManager;
  private Notification notification;
  
  @Override
  public void onReceive(Context context, Intent intent) {
      String recurID = null;
      String recurStartDate = null;
      String currentDate = null;
      String description = null;
      String type = null;
      String amount = null;
      String categoryName = null;
      String frequencyStr = null;
      String nextPaymentDate = null;
      SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
  
      DatabaseAdapter mDbHelper = new DatabaseAdapter(context);
      mDbHelper.createDatabase();
      mDbHelper.open();
      RecurringController rc = new RecurringController(mDbHelper.open());
      ArrayList&lt;RecurringModel&gt; recur_list = rc.getAllRecurring();
  
      // THIS PART TO GET DATA FROM DATABASE
      for (int i = 0; i &lt; recur_list.size(); i++) {
          recurID = recur_list.get(i).getRecurringID();
          recurStartDate = recur_list.get(i).getRecurringStartDate();
          currentDate = dateFormat.format(new Date());
          description = recur_list.get(i).getRecurringDesc();
          type = recur_list.get(i).getRecurringType();
          amount = Float.toString(recur_list.get(i).getRecurringAmount());
          categoryName = recur_list.get(i).getCategoryID();
          frequencyStr = recur_list.get(i).getFrequency();
  
          Toast.makeText(context,
                      description, Toast.LENGTH_LONG)
                      .show();
          Toast.makeText(context,
                      recurStartDate Toast.LENGTH_LONG)
                      .show();
  
          Calendar cal = Calendar.getInstance();
          try {
              cal.setTime(dateFormat.parse(recurStartDate));
              if (frequencyStr.equals("Daily")) {
                  cal.add(Calendar.DAY_OF_MONTH, 1);
                  nextPaymentDate = dateFormat.format(cal.getTimeInMillis());
                  cal.add(Calendar.DAY_OF_MONTH, -1);
              } else if (frequencyStr.equals("Weekly")) {
                  cal.add(Calendar.WEEK_OF_YEAR, 1);
                  nextPaymentDate = dateFormat.format(cal.getTimeInMillis());
                  cal.add(Calendar.WEEK_OF_YEAR, -1);
              } else if (frequencyStr.equals("Monthly")) {
                  cal.add(Calendar.MONTH, 1);
                  nextPaymentDate = dateFormat.format(cal.getTimeInMillis());
                  cal.add(Calendar.MONTH, -1);
              } else if (frequencyStr.equals("Yearly")) {
                  cal.add(Calendar.YEAR, 1);
                  nextPaymentDate = dateFormat.format(cal.getTimeInMillis());
                  cal.add(Calendar.YEAR, -1);
              }
          } catch (ParseException e) {
              e.printStackTrace();
          }
  
          // If dates match then execute the SQL statements
          if (currentDate.equals(nextPaymentDate)) {
              // mDbHelper.createDatabase();
              // mDbHelper.open();
              TransactionRecModel trm = new TransactionRecModel();
              CategoryController cc = new CategoryController(mDbHelper.open());
  
              trm.setDate(currentDate);
              trm.setTransDescription(description);
              trm.setType(type);
              trm.setAmount(Float.parseFloat(amount));
  
              // Get the categoryID based on categoryName
              String catID = cc.getCatIDByName(categoryName);
              trm.setCategory(catID);
  
              // Check if the recurring record exists before insert new
              // transaction record
              boolean recurExist = rc.checkRecurExist(recurStartDate,
                      description, catID);
              if (recurExist == true) {
                  TransactionRecController trc = new TransactionRecController(
                          mDbHelper.open());
                  // Check if the transaction record exists to prevent
                  // duplication
                  boolean moveNext = trc.checkTransExist(trm);
                  if (moveNext == false) {
  
                      if (trc.addTransactionRec(trm)) {
                          // Update recurring start date after insertion of
                          // transaction
                          RecurringModel rm = new RecurringModel();
                          rm.setRecurringID(recurID);
                          rm.setRecurringStartDate(currentDate);
  
                          if (rc.updateRecurringDate(rm)) {
                              mNotificationManager = (NotificationManager) context
                                      .getSystemService(Context.NOTIFICATION_SERVICE);
                              PendingIntent contentIntent = PendingIntent
                                      .getActivity(
                                              context,
                                              Integer.parseInt(intent
                                                      .getExtras()
                                                      .get("NotifyCount")
                                                      .toString()),
                                              new Intent(), 0);
                              notification = new Notification(
                                      R.drawable.ic_launcher, "Notification",
                                      System.currentTimeMillis());
                              notification.setLatestEventInfo(context,
                                      description, nextPaymentDate,
                                      contentIntent);
                              mNotificationManager
                                      .notify(Integer.parseInt(intent
                                              .getExtras().get("NotifyCount")
                                              .toString()), notification);
                              mDbHelper.close();
                          }
                      }
                  }
              }
              mDbHelper.close();
          }
      }
      mDbHelper.close();
      Recurring.updateAlarmLastRun(context);
  }
  }
  </code></pre>
  
  <p>I've added this part of codes in the part you suggested to schedule the alarm to call the BootReceiver class. Then from BootReceiver class, I will call back to the Recurring class and Reminder Alarm class:</p>
  
  <pre><code>ComponentName receiver = new ComponentName(context, BootReceiver.class);
      PackageManager pm = context.getPackageManager();
  
      pm.setComponentEnabledSetting(receiver,
              PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
              PackageManager.DONT_KILL_APP);
  </code></pre>