17

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

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

有人看到我做错了什么,还是我做错了?感谢您的帮助。

4

2 回答 2

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设置为接收的情况下运行这段代码BOOT_COMPLETED

我已经编写了一个关于创建Service和使用 s的指南AlarmManager,它基于我自己的经验以及我从观看 Google I/O 演讲中挑选的一些提示和技巧。如果你有兴趣,你可以在这里阅读。


要在下面回答您的问题,我所能做的就是引用文档

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

安排触发时间要求不准确的重复警报;例如,每小时重复一次的警报,但不一定在每小时的开头。这些警报比 setRepeating(int, long, long, PendingIntent) 提供的严格重复更省电,因为系统可以调整警报的相位以使它们同时触发,避免不必要地从睡眠中唤醒设备。

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

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

于 2010-12-13T16:36:17.613 回答
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.
    }
于 2013-07-24T09:20:13.823 回答