Android操作\u日期\u更改广播

Android操作\u日期\u更改广播,android,android-intent,broadcastreceiver,android-broadcast,Android,Android Intent,Broadcastreceiver,Android Broadcast,我有一个Nexus S,当我在手机上手动更改日期时,不会总是广播更改的日期。如果我将日期从2014年2月13日更改为2014年2月14日,我还没有将行动日期更改为工作日期,但如果我将其设置为未来几年,我有时会将其触发 我可以(99%)向你保证,我没有误用意图过滤器、广播接收器等。我只是好奇为什么这个广播的文档记录得如此糟糕。通过SO&Google的快速扫描显示,人们不确定这是在用户手动更改它时发生的,还是在每天12:00日期滚动时发生的,或者两者兼而有之。我的经验表明,关于用户更改,这是非常不一

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

我可以(99%)向你保证,我没有误用意图过滤器、广播接收器等。我只是好奇为什么这个广播的文档记录得如此糟糕。通过SO&Google的快速扫描显示,人们不确定这是在用户手动更改它时发生的,还是在每天12:00日期滚动时发生的,或者两者兼而有之。我的经验表明,关于用户更改,这是非常不一致的,我还没有尝试过系统更改

我将遍历AOSP代码,并隔离所有触发此代码的点,然后报告


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

我也遇到了同样的问题。我注意到,即使同时使用
ACTION\u TIME\u CHANGED
ACTION\u DATE\u CHANGED
时,我也无法始终检测到日期何时更改。我认为这是平台上的一个bug


因此,我为
ACTION\u TIME\u添加了receiver,并在日期更改时签入回调。

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

首先,我们创建一个PendingEvent mDateChangeSender

private final PendingIntent mDateChangeSender;
然后,在AlarmManagerService.java的构造函数中,我们设置PendingContent:

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\u TIME\u勾选和Intent.ACTION\u DATE\u更改。在它的onReceive()中:

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

因此,它设置了一个一次性警报,从当前时间开始,然后将小时/分钟/秒/毫秒设置为零,再加上一天,因此如果今天是下午1:30,它下一次被解雇将是在10小时30分钟后

这并不是说这里没有bug或任何东西,但看起来改变日期的行动应该在每天午夜开始

现在——如果我要改变电话上的日期,比如说10年后。处理时间变更的代码将触发第一个ACTION_DATE_CHANGED事件,然后计划一个新ACTION_DATE_CHANGED以在10年+一天的某个时间内被触发。然后,如果我们将日期改回10年,改为正确的日期,警报仍将在10年后触发,因此更改的操作日期将不再被触发(除非您将日期设置为10年以后的时间-尝试!)


tl;dr:这是安卓系统中的一个bug。

与ZachM的研究相匹配,记录了一个AOSP bug,在时钟向后设置后,
操作日期更改后
不会再次触发,直到时钟赶上第二天的时间

(还有一个关于此广播中的多小时延迟的注释。设置测试时钟或设备睡眠时更改日期的后果?)

在bug之外,
ACTION\u DATE\u CHANGED
表示时钟已到第二天,而
ACTION\u TIME\u CHANGED
(=
“android.intent.ACTION.TIME\u SET”
)表示时钟已设置(调整)

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

编辑 AOSP bug#2880有一个新的注释指出了
scheduleDateChangedEvent()
中的一个(另一个?)bug:它调用
calendar.set(calendar.HOUR,0)
,第一个参数应该是
一天中的小时数

发件人:

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

24小时时钟使用一天中的小时。例如,在晚上10:04:15.250,一天的时间是22点


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

您实际上可以使用BroadcastReceiver。只要使用动作,时区也改变了

我已经为此制定了一个很好的解决方案,如下所示:


我自己也看到了这一点,所以很可能不是你的错。不过,问题是什么?:)好问题:-)与其说是一个真实的问题,不如说是一个信息请求,但我仍然认为这样做可能有用。哦,这是关于为什么没有任何解决办法:)是的,但你的答案仍然很好(我在评论!)下面是我要说的:我现在正在浏览3个源代码树,所以我会四处看看,看看是否可以分离出发生了什么,但很高兴知道,不仅仅是我有这个问题(而且每次日期更改时,动作时间更改似乎都会触发,所以这可能是一个成本较低的解决方法!)。另外,我特别针对API 14+,因此我正在搜索AOSP 4.0.3_r1、4.2.2_r1和一些4.4分支,以供感兴趣的人使用!好吧,我把它拿回去了,它可能对某些人有用。对很多人来说,这些意图确实很棘手,也没有什么神秘之处。谢谢!对于处理此问题的其他人,当使用API 14(在运行4.0.3_r1的Nexus S上运行)时,每当我手动更改时间和时区时,我都会成功地更改操作时间和时区。如果我要修补此问题,我可能会将ClockReceiver设置为也接收更改的操作时间,检查是否需要删除旧的日期更改报警,如果需要,请将其删除并重置。当我有空的时候,我会在我自己的AOSP副本上试试这个。如果你比我先为AOSP写补丁,那么请随意参考我的帖子!直到api23仍然没有解决问题。哇,他们把它改成了过时的/无法修复的。有人知道这个问题的现状吗?如果它仍然损坏,我将提交一个补丁…这是一个很好的解决方案,但除非我理解错误(4年前:-)
...
else if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) {
...
    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);
}