Alarm Manager意外地广播

时间:2018-04-04 22:13:43

标签: android alarmmanager unix-timestamp milliseconds

我有一个应用程序应该在存储在数据库中的指定时间启动警报。 时间存储为(HH:mm)格式,24小时格式。

这是代码。

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
String temp = h+":"+m;
Date date = sdf.parse(temp);
alarmMgr = (AlarmManager)_c.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(_c, AlarmBroadcastReciever.class);
alarmIntent = PendingIntent.getBroadcast(_c, requestCode, intent, 0);
alarmMgr.set(AlarmManager.RTC_WAKEUP,Calendar.getInstance().getTimeInMillis()+  date.getTime(), alarmIntent);

_c:上下文变量 h是小时(24小时格式),m是分钟。

我想在凌晨4:30发出警报,但它在凌晨03:09:35立即被解雇。

如何在特定时间(无重复)仅安排一次警报?

PS:我倾向于使用警报,因为应用程序需要根据数据库查询在动态时间重复警报。

1 个答案:

答案 0 :(得分:2)

    int h = 4;
    int m = 30;
    LocalTime alarmTime = LocalTime.of(h, m);
    ZoneId zone = ZoneId.of("Asia/Kolkata");
    long alarmTimeMillis = LocalDate.now(zone)
            .atTime(alarmTime)
            .atZone(zone)
            .toInstant()
            .toEpochMilli();
    System.out.println(alarmTimeMillis);
    System.out.println(Instant.ofEpochMilli(alarmTimeMillis));

今天我跑这个时,输出是

1522882800000
2018-04-04T23:00:00Z

要检查1 522 882 800 000的毫秒值是否正确,我将其转换为Instant。实例始终以UTC格式打印,因此打印时间与亚洲/加尔各答时区的上午4:30(偏移+05:30)一致。您可能希望添加一个检查以查看时间是否已经过去,如果是,则添加一天以便明天在指定时间发生警报。 LocalDate和其他一些类有plusDays方法。

如果您将警报时间作为数据库中的04:30之类的字符串,请按以下方式解析:

    String alarmTimeString = "04:30";
    LocalTime alarmTime = LocalTime.parse(alarmTimeString);

其余的都一样。

我正在使用并推荐现代Java日期和时间API java.time。由于SimpleDateFormat非常麻烦,因此其朋友DateCalendar也已过时。现代API可以更好地使用。

您的代码出了什么问题?

计算闹钟时间有两个错误:

  1. 虽然您的解析会产生一个Date打印,例如Thu Jan 01 04:30:00 IST 1970,因此看起来正确,这是骗人的。 04:30:00在您当地的时区。当您使用date.getTime()时,您将获得自纪元以来的毫秒数,并且纪元数以UTC定义,而不是您的时区。例如,我使用亚洲/加尔各答时区,得到毫秒-300万,等于减去 1小时。
  2. Calendar.getInstance().getTimeInMillis()现在给出时间。在此时间内添加毫秒时,您可以指定从现在开始的毫秒数的警报时间 - 在我的示例中为1小时前的警报时间。
  3. 问题:我可以在Android上使用java.time吗?

    是的,java.time适用于较旧和较新的Android设备。它只需要至少Java 6

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

    链接