如何设置重复的AlarmManager以每天执行代码

时间:2010-12-13 16:11:29

标签: android notifications alarmmanager

我目前正在尝试编写警报管理器,每天在指定的时间段内发出警报。首先,我检查用户是否已为当天设置了警报:

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

然后我去设定实际的闹钟,在第二天的12点到12点10分之间熄灭:

     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);

 }

现在我为此设置一个测试环境,每隔两分钟就会启动一次,它似乎工作正常,但是当我部署到实际设备时,接收器似乎没有收到警报。我认为这可能是设备处于睡眠状态的问题,所以我添加了电源管理器。但它仍然无效:

      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();

任何人都会看到我公然做错的事情,或者我不正确地做错了吗?感谢任何和所有的帮助。

2 个答案:

答案 0 :(得分:44)

我通常会做更多的事情:

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);

这样,您就不必担心重新设置AlarmManager中的Service

我的应用程序启动时(我的主要活动中为onResume)和设置为接收BroadcastReceiver的{​​{1}}通常会运行此代码。

我已经写了一篇关于创建BOOT_COMPLETED和使用Service的指南,这是基于我自己的经验和一些提示&我从观看谷歌I / O谈话中挑选出来的技巧。如果您有兴趣,可以阅读here


要回答下面的问题,我所能做的就是引用the docs

AlarmManager
     

安排具有不准确触发时间要求的重复警报;例如,每小时重复一次的警报,但不一定在每小时的顶部重复。这些警报比setRepeating(int,long,long,PendingIntent)提供的严格重复更节能,因为系统可以调整警报的阶段以使它们同时触发,从而避免将设备从睡眠状态唤醒到超过必要的程度。 / p>      

您的闹钟的第一次触发不会在请求的时间之前,但在此之后几乎整整一段时间内可能不会发生。此外,虽然重复警报的整个周期将按照要求进行,但警报的任何两次连续发射之间的时间可能会有所不同。如果您的应用程序需要非常低的抖动,请改用setRepeating(int,long,long,PendingIntent)。

总之,它不是很清楚。文档只说警报“可能会有所不同”。但是,重要的是要知道第一个触发器在此之后几乎整整的时间间隔内可能不会发生

答案 1 :(得分:4)

这是有效的,每隔5秒就会发出警报

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.
    }