【问题标题】:date and time not working in Alarm Manager日期和时间在警报管理器中不起作用
【发布时间】:2019-09-01 06:45:32
【问题描述】:

我在使用 AlarmManager 时遇到问题。我想在特定时间使用日历运行AlarmManager。 但是日历不起作用,AlarmManager 始终运行,无论从日历中花费的时间如何。

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

AlarmManager 应该在每天上午 11:55 运行,但会在应用打开后立即运行。

【问题讨论】:

  • 请不要编辑您所询问的错误。当您这样做时,您的问题将不再有意义,并且会让其他读者感到困惑和困惑。
  • 仅供参考,存在严重缺陷的日期时间类,例如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat,现在已被 java.time 类所取代。大多数 java.time 功能在 ThreeTen-Backport 项目中被反向移植到 Java 6 和 Java 7。进一步适用于ThreeTenABP 中的早期 Android (How to use ThreeTenABP…

标签: android calendar alarmmanager android-pendingintent


【解决方案1】:
  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
}

试试这个..

【讨论】:

  • 对它的帮助方式和原因进行一些解释可能真的很好......
【解决方案2】:

java.time 和 ThreeTenABP

要获取您的警报管理器的 triggerAtMillis 参数的纪元以来的时间(以毫秒为单位):

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

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

你的代码出了什么问题?

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

    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。那么我们如何得到三月?这是Calendar 的另一个令人困惑的特征,月份的编号从一月的 0 到十二月的 11,因此 2 表示三月。年份字段是字段 3,月份字段是字段 5。这说明了您获得的日期。

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

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

  • 在 Java 8 及更高版本以及更新的 Android 设备(从 API 级别 26 起)中,现代 API 是内置的。
  • 在非 Android Java 6 和 7 中,获取 ThreeTen Backport,这是现代类的后向端口(对于 JSR 310,ThreeTen;请参阅底部的链接)。
  • 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从 org.threeten.bp 导入日期和时间类以及子包。

链接

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多