我需要Android应用程序发送通知,以便在每天上午8点,下午3点和晚上8点提醒用户。因此,当应用程序启动时,我在MainActivity的onCreate()中使用以下三行。但是,当我运行应用程序时,所有三个通知都会立即发生,而不是在需要的时间。
setRepeatedNotification(1,8,0,0);
setRepeatedNotification(2,15,0,0);
setRepeatedNotification(3,20,0,0);
为什么?我还在这里附加了setRepeatedNotification函数。谢谢!
private void setRepeatedNotification(int ID, int hh, int mm, int ss) {
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent alarmIntent = new Intent(MainActivity.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, ID, alarmIntent, 0);
Calendar calendar = Calendar.getInstance();
// calendar.set();
calendar.set(Calendar.HOUR_OF_DAY, hh);
calendar.set(Calendar.MINUTE, mm);
calendar.set(Calendar.SECOND, ss);
// Clear previous everyday pending intent if exists.
if (null != mEverydayPendingIntent) {
alarmManager.cancel(mEverydayPendingIntent);
}
mEverydayPendingIntent = pendingIntent;
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, mEverydayPendingIntent);
}
答案 0 :(得分:6)
我发现使用AlarmManager进行设置可能存在两个问题。第一个出现在设备进入睡眠状态时。
来自AlarmManager的文档:
如果警报延迟(例如,系统睡眠,非_WAKEUP警报类型),将尽快传递跳过的重复。之后,将根据原计划发送未来的警报;他们不随时间漂移。例如,如果您在每小时的顶部设置了定期闹钟,但手机在7:45至8:45之间处于睡眠状态,则一旦手机唤醒就会发出警报,然后将在下一次发出警报9:00。
正如您所看到的,如果您设置了闹钟并且设备已经进入休眠状态,而不使用AlarmManager.RTC_WAKEUP
则可能会有很长的延迟,具体取决于设备处于休眠状态的时间。如果您从未接触过您的设备,并且没有其他警报导致唤醒,则可能导致所有警报在设备唤醒的下一个小时内堆叠起来。
我看到的另一个潜在问题是你正在检索一个代表现在时间的Calendar实例,然后自己设置小时,分钟和秒。当前时间和当前年份已从当前时间自动填充。
再次,从文档(强调我的):
如果声明的触发时间过去,则会立即触发警报,警报计数取决于触发时间相对于重复间隔的过去程度。
在这种情况下,如果您的方法是在给定日期的晚上8点之后调用的,calendar.getTimeInMillis()
将为所有三个警报返回过去的时间戳,导致它们从上午8点,下午3点开始立即触发当天晚上8点已经过去。在这种情况下,您必须首先评估当前时间是否超过您尝试设置的警报间隔,并在设置时增加1天以确保将来设置警报。
答案 1 :(得分:6)
以下是更新后的代码:
private void setRepeatedNotification(int ID, int hh, int mm, int ss) {
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent alarmIntent = new Intent(StartActivity.this, AlarmReceiver.class);
alarmIntent.putExtra("ID",ID);
Log.d("setRepeatedNotification", "ID:" + ID);
PendingIntent pendingIntent = PendingIntent.getBroadcast(StartActivity.this, ID, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
Calendar now = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hh);
calendar.set(Calendar.MINUTE, mm);
calendar.set(Calendar.SECOND, ss);
//check whether the time is earlier than current time. If so, set it to tomorrow. Otherwise, all alarms for earlier time will fire
if(calendar.before(now)){
calendar.add(Calendar.DATE, 1);
}
mEverydayPendingIntent = pendingIntent;
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, mEverydayPendingIntent);
}