2010-12-13 33 views
15

我目前正在尝试编写报警管理器,每天在指定的时间段内发出报警。首先,我检查,看看用户是否已为这一天的报警设置:如何设置周期性AlarmManager每天执行代码

​​

然后我去设置实际报警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(); 

任何人都看不到我做的公然错还是我这个错误?感谢任何和所有的帮助。

回答

43

我通常做一些沿的线条更:

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

这样,您就不必担心重新设置AlarmManagerService

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

我已经写了一个关于创建Service s和使用AlarmManager的指南,这是基于我自己的经验和一些技巧&我从观看Google I/O谈话中摘取的技巧。如果你有兴趣,你可以阅读它here


下面来回答你的问题,我所能做的就是报价the docs

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

计划有不准确的触发时间要求重复报警;例如,每小时重复一次的警报,但不一定每小时都重复一次。与由setRepeating(int,long,long,PendingIntent)提供的严格重现相比,这些警报功耗更高,因为系统可以调整警报的相位以使它们同时触发,避免超过必要的唤醒设备。

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

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

+0

我认为,服务可能比我更需要我在做什么拍后报警,但你的博客是一个很好看的!你碰巧知道SetInexactRepeating通常有多少偏移量? – ninjasense 2010-12-13 17:52:32

+1

我编辑了我的答案来解释'setInexactRepeating'问题。 – Felix 2010-12-14 10:45:40

+3

作为奖励,而不是在设置新的之前取消,您可以检索PendingIntent和PendingIntent.FLAG_CANCEL_CURRENT作为最后一个参数,它具有相同的效果。 – nsL 2013-10-18 17:12:51

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

setInexactRepeating和setRepeating之间的区别是什么? – 2013-09-23 07:05:14

+0

http://developer.android.com/reference/android/app/AlarmManager.html – 2013-09-23 07:35:42

+1

安排具有不精确的触发时间要求的重复警报;例如,每小时重复一次的警报,但不一定每小时都重复一次。与由setRepeating(int,long,long,PendingIntent)提供的严格重现相比,这些警报功耗更高,因为系统可以调整警报的相位以使它们同时触发,避免超过必要的唤醒设备。 – 2013-09-23 07:37:22