【问题标题】:Android ACTION_DATE_CHANGED broadcastAndroid ACTION_DATE_CHANGED 广播
【发布时间】:2014-03-12 13:37:42
【问题描述】:

我有一个 Nexus S,当我在手机上手动更改日期时,ACTION_DATE_CHANGED 并不总是广播。如果我将日期从 2014 年 2 月 13 日更改为 2014 年 2 月 14 日,我还没有让 ACTION_DATE_CHANGED 起作用,但如果我将其设置为未来几年,我有时会触发它.

我可以 (99%) 向您保证,我没有滥用 IntentFilters、BroadcastReceivers 等。我只是好奇为什么这个广播的文档记录如此差。通过 SO 和 Google 的快速扫描显示,人们不确定它是否发生在用户手动更改它时,或者当日期在每天凌晨 12:00 翻转时发生,或者两者兼而有之。我的经验表明,用户更改非常不一致,我还没有尝试过系统更改。

我将遍历 AOSP 代码并隔离所有触发此代码的点并报告回来。

编辑:问题:有人知道这里发生了什么吗? :-)

【问题讨论】:

  • 我自己也看到了这个,所以很可能不是你的错。不过,问题是什么? :)
  • 很好 :-) 更像是一个信息请求而不是一个真正的问题,但我仍然认为它可能对 SO 有用。
  • 哦,这是关于为什么而不是有任何解决方法:)
  • 是的,但你的回答仍然很好(我在评论它!)这就是我要说的:我现在正在搜索 3 棵源代码树,所以我会四处看看如果我可以隔离正在发生的事情,但很高兴知道不仅仅是我有这个问题(ACTION_TIME_CHANGED 确实似乎每次日期更改时都会触发,所以这可能是一种成本较低的解决方法! )。另外,我特别针对 API 14+,所以我正在搜索 AOSP 4.0.3_r1、4.2.2_r1 和一些 4.4 分支,供感兴趣的人参考!
  • 好的,我收回了,它可能对某人有用。对许多人来说,这些 Intent 确实很棘手,而且并不神秘。

标签: android android-intent broadcastreceiver android-broadcast


【解决方案1】:

我也遇到了同样的问题。我注意到即使同时使用ACTION_TIME_CHANGEDACTION_DATE_CHANGED,我也无法始终检测到日期何时更改。我认为这是平台的错误。

所以我为ACTION_TIME_TICK 添加了接收者,并在日期更改时签入该回调。

【讨论】:

  • 谢谢!对于其他处理此问题的人,在使用 API 14(在运行 4.0.3_r1 的 Nexus S 上运行)时,我每次手动更改时间和时区时都会成功获得 ACTION_TIME_CHANGED 和 ACTION_TIMEZONE_CHANGED。
【解决方案2】:

这是 frameworks/base/services/java/android/server/AlarmManagerService.java 中 4.0.3_r1 的代码。

首先,我们创建一个 PendingIntent mDateChangeSender;

private final PendingIntent mDateChangeSender;

然后,在 AlarmManagerService.java 的构造函数中,我们设置 PendingIntent:

Intent intent = new Intent(Intent.ACTION_DATE_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
mDateChangeSender = PendingIntent.getBroadcast(context, 0, intent, 0);

然后在构造函数中:

mClockReceiver.scheduleDateChangedEvent();

那么什么是 mClockReceiver?只是一个监听 Intent.ACTION_TIME_TICK 和 Intent.ACTION_DATE_CHANGED 的 BroadcastReceiver。在它的 onReceive() 中:

...
else if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) {
...
    scheduleDateChangedEvent();
}

然后,稍后我们找到方法 scheduleDateChangedEvent():

public void scheduleDateChangedEvent() {
     Calendar calendar = Calendar.getInstance();
     calendar.setTimeInMillis(System.currentTimeMillis());
     calendar.set(Calendar.HOUR, 0);
     calendar.set(Calendar.MINUTE, 0);
     calendar.set(Calendar.SECOND, 0);
     calendar.set(Calendar.MILLISECOND, 0);
     calendar.add(Calendar.DAY_OF_MONTH, 1);
     set(AlarmManager.RTC, calendar.getTimeInMillis(), mDateChangeSender);
}

所以它设置了一个一次性警报,从当前时间开始,然后将小时/分钟/秒/毫秒设置为零,然后添加一天,所以如果是今天下午 1:30,下次它会得到发射将在 10 小时 30 分钟内完成。

这并不是说这里没有错误或任何东西,但看起来 ACTION_DATE_CHANGED 应该在每天午夜触发。

现在 - 如果我要更改手机上的日期,可以说是 10 年后。处理时间更改的代码将触发第一个 ACTION_DATE_CHANGED 事件,然后安排一个新的 ACTION_DATE_CHANGED 被触发,时间为 10 年 + 一天的一小部分。然后,如果我们将日期改回 10 年,更改为正确的日期,警报仍计划在 10 年后触发,因此 ACTION_DATE_CHANGED 将不再触发(除非您将日期设置为 10 年后 - 试试吧! )。

tl;dr:这是 Android 中的一个错误。

【讨论】:

  • 如果我要修补它,我可能会将 ClockReceiver 设置为也接收 ACTION_TIME_CHANGED,检查是否需要删除旧的 DATE_CHANGED 警报,如果需要,请将其删除并重置。当我有空闲时间时,我会在我自己的 AOSP 副本上尝试一下。如果您在为 AOSP 编写补丁方面打败了我,请随时参考我的帖子!
【解决方案3】:

与 ZachM 的研究相匹配,https://code.google.com/p/android/issues/detail?id=2880 记录了一个 AOSP 错误,即在时钟向后设置后,ACTION_DATE_CHANGED 不会再次触发,直到时钟赶上第二天的时间。

(还有一条关于此广播延迟数小时的说明。设置测试时钟或设备睡眠时更改日期的结果?)

在错误之外,ACTION_DATE_CHANGED 表示时钟到达第二天,而ACTION_TIME_CHANGED (== "android.intent.action.TIME_SET") 表示时钟已设置(调整)。

ZachM 的“如果我要修补这个...”听起来像是一个很好的解决方法,在应用程序中使用这样的警报(不是广播)。

编辑

AOSP 错误 #2880 有一条新注释指出 scheduleDateChangedEvent() 中的一个(另一个?)错误:在它调用 calendar.set(Calendar.HOUR, 0); 的地方,第一个参数应该是 HOUR_OF_DAY

来自java.util.Calendar

HOUR 用于 12 小时制 (0 - 11)。中午和午夜用 0 表示,而不是用 12 表示。例如,在晚上 10:04:15.250,HOUR 是 10。

HOUR_OF_DAY 用于 24 小时制。例如,在晚上 10:04:15.250,HOUR_OF_DAY 是 22。

因此,如果scheduleDateChangedEvent() 在半天下午运行,它会将下一个闹钟安排在中午而不是午夜。

【讨论】:

  • 直到 api23 仍然没有解决问题。 . .
  • 哇,他们将其更改为已过时/无法修复。有谁知道这个问题的当前状态?如果它仍然损坏,我将提交一个补丁......
【解决方案4】:

您实际上可以使用 BroadcastReceiver。也只需使用 ACTION_TIMEZONE_CHANGED。

我已经为此做了一个很好的解决方案,在这里:

https://stackoverflow.com/a/48782963/878126

【讨论】:

  • 这是一个很好的解决方案,但除非我理解错误的问题(4 年前:-)),否则问题不在于“我该怎么做”,而在于“为什么在早期版本的Android 不会以一致的方式广播此 Intent 吗?”
  • @ZachM 真的吗?在哪些 Android 版本上?我的解决方案在那里有效吗?
  • @ZachM 我刚刚在 4.4 模拟器上进行了测试。似乎工作正常。
  • 啊,是的,我想我在另一个关于在 4.0.3 中运行的回复中的评论中详细说明了这一点。哎呀!
  • 那么从哪个版本开始运行良好,从哪个版本开始运行不佳?
猜你喜欢
  • 2011-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多