AlarmManager 在同一天设置的时间过后发出警报,setRepeating

Posted

技术标签:

【中文标题】AlarmManager 在同一天设置的时间过后发出警报,setRepeating【英文标题】:AlarmManager firing alarm past the time it was set on the same day, setRepeating 【发布时间】:2013-07-12 20:17:58 【问题描述】:

所以基本上我有这个代码,时间返回 24 小时时间并每天重复闹钟。

public setAlarm(String time, Context context)
    String[] strTime;

    strTime = time.split(":");

    int hour, min, sec;
    //set when to alarm
    hour = Integer.valueOf(strTime[0]);
    min = Integer.valueOf(strTime[1]);
    sec = 0;

    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.HOUR_OF_DAY, hour);
    cal.set(Calendar.MINUTE, min);
    cal.set(Calendar.SECOND, sec);
    //Create a new PendingIntent and add it to the AlarmManager
    Intent intent = new Intent(context, AlarmReceiverActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 19248, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager am = (AlarmManager) context.getSystemService(Activity.ALARM_SERVICE);
    am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);

无论如何,问题是当我在上午 9:10 设置闹钟时,闹钟会响起。为什么?如果设置超过系统时间,我希望它不会发出警报。前任。将闹钟设置为上午 9 点,系统时间为上午 9 点 10 分

【问题讨论】:

【参考方案1】:

我现在开始工作了。我添加了闹钟时间和当前时间的检查器。

public setAlarm(String time, Context context)
        String[] strTime;

        strTime = time.split(":");

        int hour, min, sec;
        //set when to alarm
        hour = Integer.valueOf(strTime[0]);
        min = Integer.valueOf(strTime[1]);
        sec = 0;

        long _alarm = 0;
        Calendar now = Calendar.getInstance();
        Calendar alarm = Calendar.getInstance();
        alarm.set(Calendar.HOUR_OF_DAY, hour);
        alarm.set(Calendar.MINUTE, min);
        alarm.set(Calendar.SECOND, sec);

        if(alarm.getTimeInMillis() <= now.getTimeInMillis())
            _alarm = alarm.getTimeInMillis() + (AlarmManager.INTERVAL_DAY+1);
        else
            _alarm = alarm.getTimeInMillis();               

        //Create a new PendingIntent and add it to the AlarmManager
        Intent intent = new Intent(context, AlarmReceiverActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 19248, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        AlarmManager am = (AlarmManager) context.getSystemService(Activity.ALARM_SERVICE);
        am.setRepeating(AlarmManager.RTC_WAKEUP, _alarm, AlarmManager.INTERVAL_DAY, pendingIntent);
    

【讨论】:

AlarmManager.INTERVAL_DAY+1 - 为什么要添加 +1? 因为“如果一个警报被延迟(由于系统睡眠,例如,对于非_WAKEUP警报类型),将尽快下发跳过的重复。之后,将根据以后的警报下发到原来的时间表;它们不会随着时间的推移而漂移。例如,如果您设置了每隔一小时的重复闹钟,但手机从 7:45 到 8:45 一直处于睡眠状态,则将尽快发送闹钟手机唤醒,然后下一个闹钟将在 9:00 发送。“所以,如果您在同一天设置闹钟,闹钟就会响起【参考方案2】:

接受的答案是错误的,因为我尝试了它然后想出了解决方案。

这是错误的,因为您可以在此处看到: Calendar now = Calendar.getInstance(); Calendar alarm = Calendar.getInstance(); alarm.set(Calendar.HOUR_OF_DAY, hour); alarm.set(Calendar.MINUTE, min); alarm.set(Calendar.SECOND, sec);

“现在日历”和“日历警报”无论如何都将始终相同,因为它们在代码中几乎完全相同的位置执行相同的操作,因此 Calendar.getInstance() 将始终相同。

解决办法是这样的

    long _alarm;
    Calendar now = Calendar.getInstance();
    long oldtimer = now.getTimeInMillis();

    cal.set(Calendar.HOUR_OF_DAY, Hours2int);
    cal.set(Calendar.MINUTE, minutes2int);
    cal.set(Calendar.SECOND, cur_cal.get(Calendar.SECOND));
    cal.set(Calendar.MILLISECOND, cur_cal.get(Calendar.MILLISECOND));
    cal.set(Calendar.DATE, cur_cal.get(Calendar.DATE));
    cal.set(Calendar.MONTH, cur_cal.get(Calendar.MONTH));

    //Calendar alarm = Calendar.getInstance();

    long newtimer = cal.getTimeInMillis();


    if(newtimer < oldtimer) 
        //do the thing
    

【讨论】:

或者更简单:if (cal.getTimeInMillis() &lt; System.currentTimeMillis()) cal.add(Calendar.DATE, 1); 【参考方案3】:

使用 setInexactRepeating 代替 setRepeating

    Calendar cal= Calendar.getInstance();
    cal.set(Calendar.HOUR_OF_DAY, 9);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    PendingIntent pi = PendingIntent.getService(context, 0,
        new Intent(context, MyClass.class),PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
   am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
                            AlarmManager.INTERVAL_DAY, pi);

【讨论】:

当你想准确地发出警报时developer android 还是有同样的问题..Intent intent = new Intent(context, AlarmReceiverActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(context, 19248, intent, PendingIntent.FLAG_CANCEL_CURRENT); AlarmManager am = (AlarmManager) context.getSystemService(Activity.ALARM_SERVICE); am.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent); 好的。让我再告诉你一个例子。我希望我的设备每天早上 9 点发出警报。如果系统时间已经是上午 9 点 10 分,我将闹钟设置为上午 9 点。设置完成后,闹钟会响起。此实例使用 .setReapeting 发生。如果设置超过系统时间,如何防止它报警? 我的下一条评论是只添加支票 :) 很高兴它终于奏效了 :)

以上是关于AlarmManager 在同一天设置的时间过后发出警报,setRepeating的主要内容,如果未能解决你的问题,请参考以下文章

android alarmmanager如果设置过去的时间就会触发广播?

Android AlarmClock() ,设置闹钟日期

alarmManager 设置警报以在准确时间而不是分数工作

如何在android中向AlarmManager添加3个日期

如何设置多个AlarmManager?

使用 AlarmManager 设置重复通知 - Android