Android系统时间更新机制

来源:互联网 发布:数据周报模板xls 编辑:程序博客网 时间:2024/06/05 16:26

系统设置–日期和时间–自动确定日期和时间: 
智能机 提供2类日期和时间同步方式: 
使用网络提供时间 
使用GPS提供时间 
以及”自动确定时区“的选项。 
Android 之时间和日期的自动同步 
那就是说,我们可以通过如下3种方式自动设置我们的时间和日期: 
A、可以分别从SIM1和SIM2卡的无线通信网络(2G/3G/4G)获得 
B、通过WiFi连接到Internet网络获得 
C、透过本身自带的GPS模块接受GPS卫星信息获得 
注: 
A方式需要打开SIM1或者SIM2卡的数据连接 
C方式需要安装GPS定位应用,且只有当GPS定位成功后才会生效。

下面我们来学习一些基本概念 
GMT 
格林威治标准时间(Greenwich Mean Time) 
是指位于伦敦郊区的皇家格林尼治天文台的标准时间,本初子午线即是通过该点的经线。 
UTC 
Universal TimeCoordinated 世界统一时间,世界标准时间,国际协调时间 
UTC是基于GMT, 由原子钟提供的更准确的同一时间。 
Time zone 
时区,亦作 time belt。 
以英国格林威治天文台的本初子午线为基点,全球划分为24个时区,每区各占经度15°以本初子午线为中央经线的时区为零时区,由零时区向东、西各分12区。 
最后的东、西12区都是半时区,共同使用180°经线的地方时。每个时区的中央经线上的时间就是这个时区内统一采用的时间,称为区时,相邻两个时区的时间相差1小时。 
Local time 
地方时,本地时间。 
是以观测者子午线为参考点的时间标准,反映当地的自然时间。 
中国把首都北京所在的东8区的时间作为全国统一的时间,称为北京时间。

其实,整个世界可以就使用GMT/UTC就够了,但是各地的日出日落的自然生活反映到时间上就不那么自然了: 
伦敦人假设8点钟吃早饭, 北京人吃早饭就是16点。 
时区的划分和本地时间的使用, 就很好的解决了这个问题。

从技术实现方面再来解释一下 
通过网络同步时间,涉及到两个协议:NITZ和NTP。 
它们使用的条件不同,可以获取的信息也不一样; 
勾选这个功能后,手机首先会尝试NITZ方式,若获取时间失败,再会尝试使用NTP方式。

NITZ(network identity and time zone) 
NITZ是一种GSM/WCDMA基地台方式,必须插入SIM卡,且需要operator支持; 
可以提供时间和时区信息。 
中国大陆运营商基本是不支持的。(据说成都地区的中国联通支持NITZ,深圳联通却不支持。)

NTP(network time protocol) 
单纯通过网络(GPRS/EDGE/3G/HSPA/WiFi)获取时间,只提供时间信息,没有时区信息。 
NTP在无SIM卡或operator不支持NITZ时使用。 
因此在不支持NITZ的地区,自动获取时区功能实际上是无效的。 
它根据获取到的GMT时间,按照手机本身设置的时区信息,计算出本地时间,显示在设备上。NTP还有一种缓存机制:当前成功获取的时间会保存下来,当用户下次开启自动更新时间功能时,会结合手机clock来进行时间更新。 
这也是没有任何网络时手机却能自动更新时间的原因。 
此外,因为NTP是通过网络上的时间服务器获取时间,所以时间较长时间未同步时,可能是你手机访问的时间服务器连接有问题。

使用GPS提供的时间 
当GPS 定位成功后,会根据当前时区,将GPS UTC Time转化成对应时区的local time. 
为了确保GPS能成功定位,请到室外GPS信号良好的空旷地(视野范围内无建筑物遮挡)进行测试。

名词解释: 
NITZ:NITZ(Network Identity and Time Zone)或网络标识和时区,是一种用于自动配置本地的时间和日期的机制,同时也通过无线网向移动设备提供运营商信息。NITZ是自从PHASE 2+ RELEASE 96 的GSM中的可选功能,经常被用来自动更新移动电话的系统时钟。 
NTP:NTP(Network Time Protocol)提供准确时间,首先要有准确的时间来源,这一时间应该是国际标准时间UTC。 NTP获得UTC的时间来源可以是原子钟、天文台、卫星,也可以从Internet上获取。这样就有了准确而可靠的时间源。时间按NTP服务器的等级传播。

1.在setting中勾选“自动确定时间和日期”,“自动确定时区”后只是对key值为AUTO_TIME和AUTO_TIME_ZONE的Preference进行了赋值. 
源码路径:packages/apps/Settings/src/com/android/settings/DateTimeSettings.Java 
这里写图片描述

在SystemServer里面启动NetworkTimeUpdateService服务 
这里写图片描述

NetworkTimeUpdateService中对上述的key值进行了监听,在检测到key值改变的时候,就会发送消息mHandler.obtainMessage(mMsg).sendToTarget(); 
这里写图片描述

handler接到消息后进行消息处理调用onPollNetworkTime(msg.what),发现无论是数据或者是wifi下都是调用该方法进行更新: 
这里写图片描述

在onPollNetworkTime方法中先判断是否勾选“自动更新时间”,如果没勾选直接退出,如果勾选了再看,如果更新的NITZ时间不为NOT_SET(-1),且更新间隔小于mPollingIntervalMs,mPollingIntervalMs=24小时,那么就直接更新NITZ的时间,否则用NTP同步时间。 
这里写图片描述 
这里写图片描述 
这里写图片描述

NTP服务器: 
这里写图片描述

为了修复这个bug: 
这里写图片描述

只有超出2036年了,都有这个现象,发现从NTP服务器获取的时间越界了,在下面函数做过容错即可: 
这里写图片描述 
这里写图片描述

总结: 
如果时间自动同步选项未勾选,直接返回; 
如果NITZ已同步且上次NITZ同步未超过24小时,则设置定时器24小时后再触发同步,即广播NetworkTimeUpdateService.ACTION_POLL; 
如果NTP上次成功同步超过24小时或用户勾选自动同步选项,则进行下面的NTP同步,否则同上设置定时器24小时后再触发同步; 
如果上次NTP成功同步超过24小时,则发起同步mTime.forceRefresh(); 
如果同步成功,获取此刻NTP时间ntp=mTime.currentTimeMillis(); 
如果同步时间与当前本机时间误差超过指定值阀值,则把ntp设置为本机时间SystemClock.setCurrentTimeMillis(ntp)。

千年虫: 
这里写图片描述

这里写图片描述

文章转自http://blog.csdn.net/rjdeng/article/details/48623949

0 0
原创粉丝点击