29

I have a set of alarms that I need to keep after reboot. I've tried using on an boot receiver but they won't start again. I'm not sure if I understand the boot receiver and how to then restart all the alarms. I already have one receiver for my notifications, but don't know whether I can use the same receiver or if I need a new one?

Could anyone point me to any good tutorials or help me out?

Cheers

Code :

    DatabaseHandler db = new DatabaseHandler(this);  
    List<UAlarm> alarms = db.getAllAlarms();        
    AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);  
    for (UAlarm ua : alarms) {  
        String programme = ua.getTitle();  
        String startTime = ua.getStart();  
        String endTime = ua.getEnd();  
        String nowPlaying = ua.getChannel();  
        db.addAlarm(new UAlarm(programme, startTime, endTime, nowPlaying, ""));  
        final UAlarm ut = new UAlarm();  
        ut.setTitle(programme);  
        ut.setStart(startTime);  
        ut.setEnd(endTime);  
        ut.setChannel(nowPlaying);  
        ut.setId(db.getLastEntered());  
        String [] bla = startTime.split(":");  
        int hour = Integer.parseInt(bla[0].trim());  
        int minute = Integer.parseInt(bla[1].trim());  
        minute -= 2;  
        Calendar cal = Calendar.getInstance();  
        cal.set(Calendar.HOUR_OF_DAY, hour);  
        cal.set(Calendar.MINUTE, minute);  
        Intent intenta = new Intent(this, NotificationMenu.class);  
        String name = programme;  
        intenta.putExtra("name", name);  
        intenta.putExtra("id", db.getLastEntered());  
          PendingIntent pendingIntent = PendingIntent.getBroadcast(this, ua.getId(),  
            intenta, PendingIntent.FLAG_CANCEL_CURRENT);  
          am.set(AlarmManager.RTC_WAKEUP,  
            cal.getTimeInMillis(), pendingIntent);      
    }  
}  

with NotificationMenu being the notifications, which is why I'm using the AlarmManager

user1281053
  • 377
  • 1
  • 5
  • 10

1 Answers1

48

I'm not sure if I understand the boot receiver and how to then restart all the alarms.

Just call your code to call setRepeating() (or whatever) on AlarmManager.

For example, in this sample project, PollReceiver is set to receive BOOT_COMPLETED. In onReceive(), it reschedules the alarms:

package com.commonsware.android.schedsvc;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;

public class PollReceiver extends BroadcastReceiver {
  private static final int PERIOD=5000;

  @Override
  public void onReceive(Context ctxt, Intent i) {
    scheduleAlarms(ctxt);
  }

  static void scheduleAlarms(Context ctxt) {
    AlarmManager mgr=
        (AlarmManager)ctxt.getSystemService(Context.ALARM_SERVICE);
    Intent i=new Intent(ctxt, ScheduledService.class);
    PendingIntent pi=PendingIntent.getService(ctxt, 0, i, 0);

    mgr.setRepeating(AlarmManager.ELAPSED_REALTIME,
                     SystemClock.elapsedRealtime() + PERIOD, PERIOD, pi);
  }
}
CommonsWare
  • 910,778
  • 176
  • 2,215
  • 2,253
  • 1
    Thanks for sharing but why am I not seeing `BOOT_COMPLETED` in your code @CommonsWare? – ericn Sep 13 '13 at 02:29
  • 7
    @fuzzybee: You apparently failed to click on the hyperlink in the answer to examine the entire project, including its manifest. – CommonsWare Sep 13 '13 at 11:07
  • @CommonsWare is AlarmManager best way to get interval updates, There are few other ways to implement it like TimerTask etc. Which should we use??? – Ahmad Raza Dec 04 '13 at 13:16
  • For me its sending one more time additionally,while we switch on our device also – Karthick M Dec 05 '13 at 08:03
  • +1 for implementing your OWN external link. Makes it a more reliable answer in my opinion. – grepsedawk Mar 21 '14 at 21:59
  • I feel it's important to point out that specifying `0` for the flags parameter in `PendingIntent.getService()` will prevent extra's from being passed to the receiver. – Someone Somewhere Jan 28 '15 at 22:31
  • @SomeoneSomewhere: I'm not aware that this is the case. It will prevent extras from any existing matching `PendingIntent` being changed. – CommonsWare Jan 28 '15 at 23:07
  • This is too weird, yesterday my app was unable to read a string with Intent.getStringExtras() or Bundle.getString() - until I started to use `PendingIntent.FLAG_UPDATE_CURRENT` Today, that's not the case. Sorry - I didn't mean to mislead but I guess the Twilight Zone is real :-D – Someone Somewhere Jan 29 '15 at 19:27
  • hmmm, no I reproduced it again... I was unable to pull a string out of a bundle until I specified `PendingIntent.FLAG_UPDATE_CURRENT` – Someone Somewhere Jan 30 '15 at 01:18
  • @SomeoneSomewhere: Well, again, `0` means "don't update the extras". So if you didn't have an extra with that key when the `PendingIntent` was first created, you may not wind up with that extra when you try to create an equivalent `PendingIntent` later. If you're using extras, using one of the flags (e.g., `FLAG_UPDATE_CURRENT`) is a good idea. If you are not using extras, you don't need it. In my sample, I am not using extras. – CommonsWare Jan 30 '15 at 01:22
  • yeah I was thinking that too, but at the moment my app cancels all of its alarms whenever it is launched. So when it sets alarms any alarm should be "fresh" and not update an existing alarm. I wish it were possible to list all alarms currently set. – Someone Somewhere Jan 30 '15 at 18:00
  • If it is not working for someone then please be sure that you included permission – bakua Jun 29 '15 at 07:00
  • @CommonsWare Is there anything in this solution I should be worried about regarding the wakelock ? I want to do something similar but the service might run for a while before it's done. – Pablo Mar 26 '16 at 21:52
  • (My current code only runs once every boot and is using `startWakefulService` from a WakefulBroadcastReceiver, due to some things I read about the device sleeping before the service starts) – Pablo Mar 26 '16 at 21:58
  • @Pablo: If you are not handling your own `WakeLock`, but instead are using the one in `WakefulBroadcastReceiver`, and if "run for a while before it's done" is just a matter of a long-running `onHandleIntent()`, you should be OK, if your work is pretty sure to be done in less than a minute. That is the maximum time `WakefulBroadcastReceiver` will hold its `WakeLock` before automatically releasing it. If your work might be longer than that, then `WakefulBroadcastReceiver` and `IntentService` might not be the best pattern for you. – CommonsWare Mar 26 '16 at 22:02
  • @CommonsWare I am not handling my own WakeLock on the service. The operation is likely to run under 1 minute, but I start Volley requests in the `OnHandleIntent` . Are there any problems due to its asynchronous nature? – Pablo Mar 26 '16 at 22:06
  • @Pablo: Yes, if that work might run past the end of `onHandleIntent()`. That's one of the many reasons why I don't use Volley -- it's not sufficiently flexible for use from both the UI and background threads. There are recipes for making synchronous requests with Volley, but they seemed like they were workarounds for a fundamental library limitation. I'm an OkHttp fan. :-) – CommonsWare Mar 26 '16 at 22:18
  • @CommonsWare I will give OkHttp a look, then. Many thanks! :) – Pablo Mar 26 '16 at 22:21
  • @CommonsWare I downloaded the sample to try to compare what I am doing wrong. I added a log Log.d(getClass().getSimpleName(), "startup. action="+i.getAction()); in PollReceiver.onReceive. Last night I ran it once(only once), went to bed happy that I would be able to debug this. This morning, it's not working at all..no logs at all when I start it. I will be adding more and more detail to this post as I debug further https://stackoverflow.com/questions/63293900/code-in-trying-to-reschedule-previous-alarm-notifications-in-android-after-a-reb – Dean Hiller Aug 07 '20 at 12:46
  • @DeanHiller: This answer is from 2012. Nowadays, Doze mode, app standby, and manufacturer power limiters really restrict `AlarmManager` and other periodic background triggers. – CommonsWare Aug 07 '20 at 13:08
  • @CommonsWare oh, I am not trying to do a repeat alarm. I am only trying to reschedule alarms that are no longer scheduled after a reboot(or somehow save them before a reboot). Is that possible? ie. I scheduled notifications to go out and I think a reboot clears those. (some of these are 2 months from the date the phone is rebooted). – Dean Hiller Aug 07 '20 at 13:25
  • @DeanHiller: "I scheduled notifications to go out and I think a reboot clears those" -- yes, that is still the case AFAIK. – CommonsWare Aug 07 '20 at 13:33
  • @CommonsWare so is the only way to reschedule by creating a service? In your example, that 'seems' to work in that the service always starts up ...... even though I don't want a service running for my app(lol). – Dean Hiller Aug 07 '20 at 18:58
  • @CommonsWare and you could post an answer in my SO post and I'll mark it correct either way! because this has been helpful and you deserve it. – Dean Hiller Aug 07 '20 at 18:58
  • @DeanHiller: "so is the only way to reschedule by creating a service?" -- frankly, I have steered clear of `AlarmManager` for a few years. Again, this answer is from 2012, back when life was simpler (anyone could do anything with `AlarmManager`, no Doze mode, no murder hornets, etc.). Back in the day, rescheduling from a boot-time receiver worked, but I have not tried any of this in a while. – CommonsWare Aug 07 '20 at 19:34
  • @CommonsWare any advice then on a new path forward? (I am only 50 hours into android development...after work in my spare time). – Dean Hiller Aug 09 '20 at 02:11
  • @DeanHiller: I would not recommend `AlarmManager` to newcomers to Android. If you are trying to do a bit of work every so often, consider `WorkManager`. – CommonsWare Aug 09 '20 at 11:05
  • @CommonsWare. sweet, thanks!!! I am just trying to make sure my notifications go off when the user wants them too(ie. it is setup by the user so they would hate for them not to get what they scheduled). thanks! – Dean Hiller Aug 09 '20 at 13:50
  • @DeanHiller: "I am just trying to make sure my notifications go off when the user wants them too" -- to be honest, I would not recommend that a newcomer to Android write an app with that functionality. For that, you would definitely need to use `AlarmManager`, and `AlarmManager` is not simple anymore. – CommonsWare Aug 09 '20 at 13:54