如何为所有用户设置AlarmManager时区?

时间:2019-04-06 22:35:31

标签: java android timezone alarmmanager

无论他们的时区是什么,或者他们的电话时间设置为什么,我都需要同时将所有用户定向到一个活动,因此我需要指定要在“ AlarmManager”中考虑的特定时区用户在手机中的时间。但是,“ AlarmManager”的“ setTimeZone”仅适用于系统应用程序。那么解决方案是什么?

这是我的代码:

Intent intent = new Intent(Start.this, Playing.class);
                        PendingIntent pendingIntent = PendingIntent.getActivity(Start.this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
                        ((AlarmManager) getSystemService(ALARM_SERVICE)).setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);

1 个答案:

答案 0 :(得分:1)

我不是Android开发人员,但是按照阅读文档的方式,这不需要做任何特殊的事情。设置警报时,您可以指定距该时间段的毫秒数。纪元的定义与时区无关。因此,如果您只是在所有设备上传递相同的triggerAtMillis值,则所有设备(无论其时区如何)都会同时发出警报。

AlarmManager也有一个setTimeZone方法,但是(1)您不需要它,(2)它可以设置整个系统的时区,您的用户可能会不想。

编辑:使用java.time获取明确的时间

由于您从calendar.getTimeInMillis()中获得了毫秒数,因此如果您输入的时间不正确,那么日历就是问题所在。

您可能想要解决此问题,方法是将ThreeTenABP添加到您的Android项目中,以便您可以使用java.time(现代的Java日期和时间API)来计算毫秒。请参阅底部的链接。 Calendar类的设计很差,而且已经过时了,现代的API更加易于使用,并且通常提供更清晰的代码。例如:

    ZoneId alarmZone = ZoneId.of("America/Argentina/Salta");
    ZonedDateTime alarmDateTime = ZonedDateTime.of(2019, 4, 10, 14, 30, 0, 0, alarmZone);
    long triggerAtMillis = alarmDateTime.toInstant().toEpochMilli();

    System.out.println(triggerAtMillis);

输出值本身不是很有趣:

  

1554917400000

重点是,由于我们已在代码段中对时区进行了硬编码,因此无论设备时区如何,该值都将相同,因此您的警报将在所有设备上同时响起(假设时钟设置正确)。

问题:我可以在Android版本上使用java.time吗?我需要ThreeTenABP吗?

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

  • 在Java 8和更高版本以及更新的Android设备(API级别26以上)中,内置了现代API。
  • 在Java 6和7中,获得了ThreeTen反向端口,这是现代类的反向端口(JSR 310的ThreeTen;请参见底部的链接)。
  • 在(较旧的)Android上,使用Android版本的ThreeTen Backport。叫做ThreeTenABP。并确保您使用子包从org.threeten.bp导入日期和时间类。

链接