Android每天使用AlarmManager在特定时间重复通知

Yu.*_*Yu. 3 android alarmmanager

我需要Android应用程序发送通知,以便在每天上午8点,下午3点和晚上8点提醒用户.因此,当应用程序启动时,我在MainActivity的onCreate()中使用以下三行.但是,当我运行应用程序时,所有三个通知都会立即发生,而不是在需要的时间.

    setRepeatedNotification(1,8,0,0); 
    setRepeatedNotification(2,15,0,0); 
    setRepeatedNotification(3,20,0,0);    
Run Code Online (Sandbox Code Playgroud)

这是为什么?我还在这里附加了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);
}
Run Code Online (Sandbox Code Playgroud)

ini*_*mfs 6

我看到你使用AlarmManager设置的两个潜在问题.第一个出现在设备进入睡眠状态时.

从AlarmManager的文档:

如果警报延迟(例如,通过系统休眠,对于非_WAKEUP警报类型),将尽快传递跳过的重复.之后,将根据原计划发送未来的警报; 他们不随时间漂移.例如,如果您在每小时的顶部设置了定期闹钟,但手机在7:45至8:45之间处于睡眠状态,则一旦手机唤醒就会发出警报,然后将在下一次发出警报9:00.

如您所见,如果您已设置闹钟且设备已进入休眠状态,则不使用AlarmManager.RTC_WAKEUP可能会有很长的延迟,具体取决于设备处于休眠状态的时间长短.如果您从未接触过设备,并且没有其他警报导致唤醒,则可能导致所有警报在设备清醒的下一个小时内堆叠起来.


我看到的另一个潜在问题是你正在检索一个代表现在时间的Calendar实例,然后自己设置小时,分钟和秒.从当前时间开始自动填充当前日期和当前年份.

再次,从文档(强调我的):

如果规定的触发时间是过去的,则将立即触发警报,警报计数取决于过去触发时间相对于重复间隔的距离.

在这种情况下,如果被调用过去8时许在某一天你的方法,calendar.getTimeInMillis()将过去返回一个时间戳所有三个报警,使他们立即从早上8点被触发,下午3点至晚上8点都已经是过去的那一天.在这种情况下,您必须首先评估当前时间是否超过您尝试设置的警报间隔,并在您设置的时间上再添加1天,以确保将来设置警报.


Yu.*_*Yu. 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);



}
Run Code Online (Sandbox Code Playgroud)