本文涉及内容:
一,如何设置多个AlarmManager提醒
二,多个循环的AlarmManager逻辑管理
最近在捣鼓的一个小proj涉及到需要定时提醒的问题,每天的三个特定时间到点提醒。涉及到类似问题的,我觉得AlarmManager是最佳选择,简单粗暴。因为之前就用过AlarmManager,所以感觉轻车熟路,没想到一开始就碰壁了,首先是一打开程序,就会莫名其妙地提醒,其次,存在闹钟被覆盖的问题。现在终于都搞定了,所以mark一下。
一,如何设置多个AlarmManager提醒
这里主要要解决的是多个AlarmManager会被覆盖的问题。解决这个问题,需要借助PendingIntent的request code,因为我需要的是到时间弹出一个AlertDialog提醒,所以我就用PendingIntent的getActivity方法:
public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags)
其中的requestCode就是用于区分每个PendingIntent的code。在定义多个AlarmManager提醒的时候需要特别注意,每个提醒的requestCode的独特性,不可都设成一个值。其实仔细一想也非常好理解,就像要cancel一个AlarmManager的时候也是只需要它的PendingIntent就ok。PendingIntent是这个全局提醒到点时所需要的信差,只是这个信差是one to one的vip服务。如在我自己的小proj中,我用private static final的int来制定每个requestCode:
Intent intent = new Intent(getApplicationContext(), AlarmSetActivity.class); PendingIntent pendingIntentUp = PendingIntent.getActivity( CheckActivity.this, UP, intent, PendingIntent.FLAG_UPDATE_CURRENT); PendingIntent pendingIntentStudy = PendingIntent.getActivity( CheckActivity.this, STUDY, intent, PendingIntent.FLAG_UPDATE_CURRENT); PendingIntent pendingIntentSleep = PendingIntent.getActivity( CheckActivity.this, SLEEP, intent, PendingIntent.FLAG_UPDATE_CURRENT);
另外,提醒大家,PendingIntent中的flags May beFLAG_ONE_SHOT
,FLAG_NO_CREATE
,FLAG_CANCEL_CURRENT
,FLAG_UPDATE_CURRENT
, or any of the flags as supported byIntent.fillIn()
to control which unspecified parts of the intent that can be supplied when the actual send happens. 要是想用flags前,注意先看看文档。
二,多个循环的AlarmManager逻辑管理
因为我这里需要的多个AlarmManager是系统自定义的时间,而不是通过一个TimePickerDialog来拾取,然后又因为是一个每天循环的闹钟,所以就容易出现这样的问题,就是一打开程序,就会莫名其妙地提醒。查看了API后发现,产生这个问题的原因在于:If the time occurs in the past, the alarm will be triggered immediately. 所以在循环的时间逻辑设定上一定要注意,否则一打开,程序一看这个时间已经是past了,它就直接来一个提醒就搞笑了。这里贴上自己的判断,供大家参考:
// 计算距离下一次发送的时间 long triggerAtMillisUp = settaigger(6, 30) + System.currentTimeMillis(); long triggerAtMillisStudy = settaigger(20, 0) + System.currentTimeMillis(); long triggerAtMillisSleep = settaigger(22, 0) + System.currentTimeMillis(); long intervalMillis = 24 * 60 * 60 * 1000;// 每天重复
private static long settaigger(int h, int m) { Calendar c = Calendar.getInstance(); int hour_current = c.get(Calendar.HOUR_OF_DAY); int minute_current = c.get(Calendar.MINUTE); int hh = 0; int mm = 0; if (hour_current < h) { hh = h - hour_current; mm = m - minute_current; } else if (hour_current == h && minute_current <= m) { hh = h - hour_current; mm = m - minute_current; } else if (hour_current == h && minute_current > m) { hh = 24; mm = m - minute_current; }else if (hour_current > h) { hh = 24 - hour_current + h; mm = m - minute_current; } System.out.println("hh ==" + hh + "mm==" + mm); int millis = hh * 60 * 60 * 1000 + mm * 60 * 1000; return millis; }