如何在每月的最后一天实施每月重复警报

时间:2016-11-05 14:07:47

标签: java android android-alarms

我想在每个月末发出警报。目前,代码按指定的时间,月份和日期运行良好 - 但它仅适用于第一个月 - 后续月份不起作用。

AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

Intent alarmIntent = new Intent(MainActivity.this, AlarmReceiver.class);

pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, alarmIntent, 0);

manager.cancel(pendingIntent);

Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());

int currentMonth = calendar.get(Calendar.MONTH);
int currentYear = calendar.get(Calendar.YEAR);
calendar.set(Calendar.MONTH, currentMonth);



if (currentMonth == Calendar.JANUARY || currentMonth == Calendar.MARCH || currentMonth == Calendar.MAY || currentMonth == Calendar.JULY
    || currentMonth == Calendar.AUGUST || currentMonth == Calendar.OCTOBER || currentMonth == Calendar.DECEMBER) {
    // calendar.add(Calendar.DAY_OF_MONTH,31);
    calendar.set(Calendar.HOUR_OF_DAY, 12);
    calendar.set(Calendar.MINUTE, 30);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    calendar.set(Calendar.DAY_OF_MONTH, 31);

    manager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}

if (currentMonth == Calendar.APRIL || currentMonth == Calendar.JUNE || currentMonth == Calendar.SEPTEMBER
    || currentMonth == Calendar.NOVEMBER) {
    //  calendar.add(Calendar.DAY_OF_MONTH,30);
    calendar.set(Calendar.HOUR_OF_DAY, 12);
    calendar.set(Calendar.MINUTE, 30);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    calendar.set(Calendar.DAY_OF_MONTH, 30);

    manager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);

}

if (currentMonth == Calendar.FEBRUARY) {//for feburary month)
    GregorianCalendar cal = (GregorianCalendar) GregorianCalendar.getInstance();
    if (cal.isLeapYear(currentYear)) {//for leap year feburary month
        //calendar.add(Calendar.DAY_OF_MONTH,29);
        calendar.set(Calendar.HOUR_OF_DAY, 12);
        calendar.set(Calendar.MINUTE, 30);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 29);
        manager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);

    } else { //for non leap year feburary month
        // calendar.add(Calendar.DAY_OF_MONTH,28);
        calendar.set(Calendar.HOUR_OF_DAY, 12);
        calendar.set(Calendar.MINUTE, 30);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 28);
        manager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
    }
}

Toast.makeText(this, "will start at 12:30am", Toast.LENGTH_SHORT).show();

2 个答案:

答案 0 :(得分:1)

我建议您在AlarmReceiver课程中添加新的闹钟。

现在您只触发一个警报,这就是为什么它可以运行一个月。

onReceive()方法中获取AlarmManager并为下个月设置新闹钟。

答案 1 :(得分:0)

免责声明:我不知道AlarmManager,所以这可能不是一个好的答案,但我也想展示如何改进代码。

您似乎希望在当月的最后一天12:30 PM 运行代码(不像上一个语句那样AM),但是如果您已经过了那个时间,例如在下午1:15,您最终将警报设置为过去的时间,此时您确实需要设置下一个月结束的时间。

此外,calendar.setTimeInMillis(System.currentTimeMillis())也是多余的,因为Calendar.getInstance()也为您做了这样的事情:

  

返回的日历基于默认时区的当前时间和默认语言区域。

同样地,使用您刚提取的月份调用calendar.set(Calendar.MONTH, currentMonth)将无所作为。

要查找当月的最后一天,请致电getActualMaximum(DAY_OF_MONTH),而不是所有if次陈述。

所以,所有Calendar代码归结为此,包括超过目标时间的修复:

Calendar cal = Calendar.getInstance();
int currentYear = cal.get(Calendar.YEAR);
int currentMonth = cal.get(Calendar.MONTH);
int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
cal.clear();
cal.set(currentYear, currentMonth, lastDay, 12, 30);
if (cal.getTimeInMillis() <= System.currentTimeMillis()) {
    cal.add(Calendar.DAY_OF_MONTH, 1); // First of next month
    lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
    cal.set(Calendar.DAY_OF_MONTH, lastDay); // Last of next month
}

如果使用以下方式打印结果:

System.out.println(cal.getTime());

它给了我这个输出:

Wed Nov 30 12:30:00 EST 2016

注意:如果您想要在上午12:30而非下午12:30,只需将12更改为0,即可致电set()。< / p>