Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Set Recurring AlarmManager to execute code daily

I am currently trying to write alarm manager that will make an alarm go off within a specified period of time, daily. First I check to see if the user has had an alarm set for that for that day:

      if ((User.getReminderTime(Home.this) > 0)
    && (dt.getDate() != today.getDate() || dt.getDay() != today
      .getDay())) {
   AppointmentManager.setFutureAppointmentCheck(this
     .getApplicationContext());
   User.setLongSetting(this, "futureappts", today.getTime());
  }

Then I go and set the actual alarm to go off between 12 and 12:10 of the next day:

     public static void setFutureAppointmentCheck(Context con) {
  AlarmManager am = (AlarmManager) con
    .getSystemService(Context.ALARM_SERVICE);

  Date futureDate = new Date(new Date().getTime() + 86400000);
  Random generator = new Random();

  futureDate.setHours(0);
  futureDate.setMinutes(generator.nextInt(10));
  futureDate.setSeconds(0);

  Intent intent = new Intent(con, FutureAppointmentReciever.class);

  PendingIntent sender = PendingIntent.getBroadcast(con, 0, intent,
    PendingIntent.FLAG_ONE_SHOT);

  am.set(AlarmManager.RTC_WAKEUP, futureDate.getTime(), sender);

 }

Now I setup a test environment for this to go off every two minutes and it seems to be working fine, however when I deploy to an actual device, the reciever does not seem to be recieving the alarms. I thought it might be an issue with the device being asleep, so I added the power manager. But it still does not work:

      PowerManager pm = (PowerManager) context
    .getSystemService(Context.POWER_SERVICE);
  PowerManager.WakeLock wl = pm.newWakeLock(
    PowerManager.PARTIAL_WAKE_LOCK, "keepAlive");
  wl.acquire();
  setFutureAppointments(context.getApplicationContext());
  AppointmentManager.setFutureAppointmentCheck(context
    .getApplicationContext());
  User.setLongSetting(context.getApplicationContext(), "futureappts",
    new Date().getTime());
  wl.release();

Anyone see anything I am doing blatantly wrong or am I going about this incorrectly? thanks for any and all help.

like image 933
ninjasense Avatar asked Dec 13 '10 16:12

ninjasense


People also ask

How do you set an alarm for every hour on Android?

At the top of the main panel you should see an option to Add alarm. Tap this and you'll be presented with a time in the top half of the screen, with various settings in the lower half. Scroll the hours up or down until you reach the one you want, then repeat the process with the minutes.

How do I set an alarm for multiple days on Android?

Calendar object is used to store one specific date. Therefore, in order to get set alarms for several days, you need to set each of the alarms separately. For this reason you may create separate Calendar objects or reuse one by changing the time. However, you have same receiver class for both alarms.

How do you schedule notifications using alarm Manager explain with an example?

Handling the broadcast:Alarm service will invoke this receiver on scheduled time. Here we can trigger the local notification with the respective details(title, content, icon). The below code will help you to handle the broadcast. Now inside your onReceive() function, you need to initiate the notification.


2 Answers

I usually do something more along the lines of:

Intent i = new Intent(this, MyService.class);
PendingIntent pi = PendingIntent.getService(this, 0, i, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.cancel(pi); // cancel any existing alarms
am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
    SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_DAY,
    AlarmManager.INTERVAL_DAY, pi);

This way, you don't have to worry about re-setting the AlarmManager in your Service.

I usually run this bit of code when my app starts (onResume in my main activity) and in a BroadcastReceiver that is set up to receive BOOT_COMPLETED.

I've written a guide on creating Services and using the AlarmManager, which is based on my own experience and a few tips & tricks I picked off from watching a Google I/O talk. If you're interested, you can read it here.


To answer your question below, all I can do is quote the docs:

public void setInexactRepeating (int type, long triggerAtTime, long interval, PendingIntent operation)

Schedule a repeating alarm that has inexact trigger time requirements; for example, an alarm that repeats every hour, but not necessarily at the top of every hour. These alarms are more power-efficient than the strict recurrences supplied by setRepeating(int, long, long, PendingIntent), since the system can adjust alarms' phase to cause them to fire simultaneously, avoiding waking the device from sleep more than necessary.

Your alarm's first trigger will not be before the requested time, but it might not occur for almost a full interval after that time. In addition, while the overall period of the repeating alarm will be as requested, the time between any two successive firings of the alarm may vary. If your application demands very low jitter, use setRepeating(int, long, long, PendingIntent) instead.

In conclusion, it's not very clear. The docs only say that the alarm "may vary". However, it should be important for you to know that the first trigger might not occur for almost a full interval after that time.

like image 110
Felix Avatar answered Oct 04 '22 16:10

Felix


This is working, this will shoot alarm after every 5 seconds

private void setRecurringAlarm() {

        Logger.d(IConstants.DEBUGTAG, "Setting Recurring Alarm");

        Calendar updateTime = Calendar.getInstance();

        updateTime.set(Calendar.SECOND, 5);

        Intent alarmIntent = new Intent(this, AlarmReceiver.class);
        PendingIntent recurringDownload = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
        AlarmManager alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        alarms.cancel(recurringDownload);
        alarms.setInexactRepeating(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis(), 1000 * 5, recurringDownload); //will run it after every 5 seconds.
    }
like image 33
AZ_ Avatar answered Oct 04 '22 16:10

AZ_