如何为所有用户设置警报管理器时区?



我需要所有用户在同一时间被定向到一个活动,无论他们的时区是什么或他们的手机时间设置了什么,所以我需要指定一个特定的时区,无论用户在手机中的时间如何,都要在"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);

我不是 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吗?我需要三十ABP吗?

java.time在较旧和较新的Android设备上运行良好。它只需要至少Java6

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

链接

  • AlarmManager文档 .
  • Oracle 教程:日期时间解释如何使用 java.time。
  • Java 规范请求 (JSR) 310,其中首次描述了java.time
  • ThreeTen Backport项目,将java.time向Java 6和7的反向移植(JSR-310的ThreeTen)。
  • ThreeTenABP,ThreeTen Backport 的安卓版
  • 问:如何在Android项目中使用ThreeTenABP,并进行了非常详尽的解释。

相关内容

  • 没有找到相关文章

最新更新