使用AlarmManager在一天中的特定时间发出Android每日重复通知

使用AlarmManager在一天中的特定时间发出Android每日重复通知,android,alarmmanager,Android,Alarmmanager,我需要在Android应用程序上发送通知,提醒用户每天早上8点、下午3点和晚上8点。因此,当应用程序启动时,我在MainActivity的onCreate()中使用以下三行代码。然而,当我运行应用程序时,所有三个通知都会同时出现,而不是在想要的时间 setRepeatedNotification(1,8,0,0); setRepeatedNotification(2,15,0,0); setRepeatedNotification(3,20,0,0); 为什

我需要在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);
}

我发现您的AlarmManager设置存在两个潜在问题。第一种情况发生在设备进入睡眠状态时

从AlarmManager的文档中:

如果报警延迟(例如,对于非唤醒报警类型,由于系统睡眠),将尽快发送跳过的重复。之后,未来的警报将按照原计划交付;它们不会随时间漂移。例如,如果您已为每小时的顶部设置了一个周期性闹钟,但手机在7:45到8:45之间处于休眠状态,则手机一醒来就会发出闹钟,下一个闹钟将在9:00发出

如您所见,如果您设置了警报且设备已进入睡眠状态,而未使用
AlarmManager.RTC_WAKEUP
,则根据设备睡眠时间的长短,可能会有较长的延迟。如果您从未触摸过您的设备,并且没有其他警报导致唤醒,则可能会导致您的所有警报在设备唤醒的下一个小时堆积起来


我看到的另一个潜在问题是,您正在检索表示当前时间的日历实例,但随后自己设置小时、分钟和秒。当前日期和当前年份已从当前时间自动填充

同样,从文件(我的重点):

如果规定的触发时间已过,则会立即触发报警,报警计数取决于触发时间过去与重复间隔之间的距离


在这种情况下,如果您的方法是在给定的一天晚上8点之后调用的,
calendar.getTimeInMillis()
将为所有三个报警返回过去的时间戳,导致它们在当天上午8点、下午3点和晚上8点已经过去后立即触发。在这种情况下,您必须首先评估当前时间是否超过您试图设置的报警间隔,并在您正在设置的时间上再增加一天,以确保将来已设置报警。

以下是更新的代码:

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



}

在setRepeating方法中使用AlarmManager.RTC_WAKEUP而不是AlarmManager.RTC。AlarmReceiver是如何设置的?我们可以使用“日历”本身,而不是“现在”对象。你是怎么设置的?你能分享一下AlarmReceiver代码吗?我的马上就要开火了,我从@initramfs made@initramfs的最后一条评论中猜到了。@initramfs,你能看一下吗。