日期和时间在警报管理器中不起作用

date and time not working in Alarm Manager

我在使用 AlarmManager 时遇到问题。我想 运行 AlarmManager 在特定时间使用日历。 但是日历不起作用,并且 AlarmManager 总是 运行s,无论日历中的时间如何。

 AlarmManager mAlarmManger = (AlarmManager) Objects.requireNonNull(activity).getSystemService(view.getContext().ALARM_SERVICE);
 Intent intent = new Intent(activity, MyReceiver.class);
 PendingIntent pendingIntent = PendingIntent.getBroadcast(activity, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

 Calendar calendar = Calendar.getInstance();
 calendar.set(Calendar.WEEK_OF_YEAR, Calendar.MONTH , Calendar.DAY_OF_MONTH, 11, 55, 0);
 calendar.set(Calendar.AM_PM, Calendar.AM);

 if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O){

        mAlarmManger.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
    }
    else{

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

A​​larmManager 应在每天 11:55 上午 运行,但会在应用程序打开后立即 运行。

  Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 11);
        calendar.set(Calendar.MINUTE, 30);
        calendar.set(Calendar.SECOND, 0);     

if (calendar.getTimeInMillis() > System.currentTimeMillis()) {

            Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
            pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            AlarmManager am = (AlarmManager) MainActivity.this.getSystemService(MainActivity.this.ALARM_SERVICE);
            am.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 24 * 60 * 60 * 1000, pendingIntent); //Repeat every 24 h
}

试试这个..

java.time 和 ThreeTenABP

要获取自闹钟管理器的 triggerAtMillis 参数的纪元以来的毫秒数:

    long triggerAtMillis = ZonedDateTime.now(ZoneId.systemDefault())
            .with(LocalTime.of(11, 55))
            .toInstant()
            .toEpochMilli();

要使此代码也适用于 Oreo 之前的 Android 版本(版本代码 O,API 级别 26),请将 ThreeTenABP 添加到您的 Android 项目,请参阅 link 在底部。然后确保导入 org.threeten.bp.ZonedDateTimeorg.threeten.bp.ZoneIdorg.threeten.bp.LocalTime.

你的代码出了什么问题?

Calendar class 的设计总是很糟糕,界面也很混乱。难怪你犯了这个错误。你远不是第一个,不幸的是也不是最后一个。在您尝试的原始问题中:

    calendar.set(Calendar.WEEK_OF_YEAR, Calendar.MONTH , Calendar.DAY_OF_MONTH, 11, 55, 0);

在我所在的时区,这会将日历日期设置为 Mon Mar 05 11:55:00 CET 3。那是 2016 年和几个月前。因此,当您的应用程序一打开,警报管理器就在 运行 时做了正确的事情。可能是您将第 3 年、第 3 个月和第 5 个月的日期传递给了该方法?几乎! Calendar 接口正在处理可以独立设置的字段:时代字段、年份字段、月份字段等。由于这是在 Java 中的枚举之前设计的,每个字段都有一个数字,当然还有那个数字的命名常量。例如,月份字段是字段 2,所以当您为月份传递 Calendar.MONTH 时,您传递的是值 2。那么我们如何得到 March?这是 Calendar 的另一个令人困惑的特征,月份的编号是从 1 月的 0 到 12 月的 11,因此 2 表示 3 月。年中的星期字段是字段 3,月中的日期字段是字段 5。这解释了您获得的日期。

问题:java.time 不需要 Android API 26 级吗?

java.time 在新旧 Android 设备上都能很好地工作。它只需要至少 Java 6.

  • 在 Java 8 和更新的 Android 设备上(从 API 级别 26)内置了现代 API。
  • 在非Android Java 中,6 和 7 得到 ThreeTen Backport,现代 classes 的 backport(ThreeTen 用于 JSR 310;参见 link s 在底部)。
  • 在(较旧的)Android 使用 ThreeTen Backport 的 Android 版本。它叫做 ThreeTenABP。并确保使用子包从 org.threeten.bp 导入日期和时间 classes。

链接