【问题标题】:How to Set Recurring AlarmManager to execute code daily如何设置 Recurring AlarmManager 以每天执行代码
【发布时间】:2010-12-13 16:11:29
【问题描述】:

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

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

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

【问题讨论】:

    标签: android notifications alarmmanager


    【解决方案1】:

    我通常会做更多类似的事情:

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

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

    我通常在我的应用程序启动时运行这段代码(onResume 在我的主要活动中)并在设置为接收BOOT_COMPLETEDBroadcastReceiver 中运行。

    我已根据我自己的经验以及从观看 Google I/O 演讲中挑选的一些技巧和窍门编写了有关创建 Services 和使用 AlarmManager 的指南。有兴趣的可以阅读here


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

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

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

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

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

    【讨论】:

    • 我认为一项服务可能超出了我正在做的事情的需要,但您的博客读起来很不错!您是否知道 SetInexactRepeating 通常有多少偏移量?
    • 我编辑了我的答案来解释 setInexactRepeating 问题。
    • 作为奖励,您可以使用 PendingIntent.FLAG_CANCEL_CURRENT 作为最后一个参数来检索 PendingIntent,而不是在设置新的之前取消,这具有相同的效果。
    • 我有一个关于 PendingIntent 的问题。假设其他类使用具有相同请求代码但具有用于其他服务/活动/接收器的不同意图的警报管理器。这会是个问题吗?请求代码在整个应用程序中是否必须是唯一的?在这种情况下到底会发生什么?
    • @Felix 我读了你的博客并做了同样的事情,但我没有使用重复延迟,而是使用日历!但每次我打开应用程序都会触发警报! stackoverflow.com/questions/33981142/…
    【解决方案2】:

    这是有效的,它会在每 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.
        }
    

    【讨论】:

    • setInexactRepeating 和 setRepeating 有什么区别?
    • 安排一个不精确的触发时间要求的重复警报;例如,每小时重复一次的警报,但不一定在每小时的开头。这些警报比 setRepeating(int, long, long, PendingIntent) 提供的严格重复更节能,因为系统可以调整警报的相位以使它们同时触发,避免不必要地从睡眠中唤醒设备。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-09
    • 2011-06-01
    • 1970-01-01
    • 2016-05-03
    • 1970-01-01
    相关资源
    最近更新 更多