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
2.在/frameworks/base/services/java/com/android/server/NetworkTimeUpdateService中对上述的key值进行了监听,在检测到key值改变的时候,就会发送消息mHandler.obtainMessage(mMsg).sendToTarget();
1
2
3
4
5
6
7
8
9
10
|
void
observe(Context context) {
ContentResolver resolver = context.getContentResolver();
resolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.AUTO_TIME),
false
,
this
);
}
@Override
public
void
onChange(
boolean
selfChange) {
mHandler.obtainMessage(mMsg).sendToTarget();
}
|
handler接到消息后进行消息处理调用onPollNetworkTime(msg.what),发现无论是数据或者是wifi下都是调用该方法进行更新
1
2
3
4
5
6
7
8
9
|
public
void
handleMessage(Message msg) {
switch
(msg.what) {
case
EVENT_AUTO_TIME_CHANGED:
case
EVENT_POLL_NETWORK_TIME:
case
EVENT_NETWORK_CONNECTED:
onPollNetworkTime(msg.what);
break
;
}
}
|
3.在onPollNetworkTime方法中先判断是否勾选“自动更新时间”,如果没勾选直接退出,如果勾选了再看,如果更新的NITZ时间不为NOT_SET(-1),且更新间隔小于mPollingIntervalMs,mPollingIntervalMs=24小时,那么就直接更新NITZ的时间,否则用NTP同步时间。
1
2
3
4
5
6
|
// If NITZ time was received less than mPollingIntervalMs time ago,
// no need to sync to NTP.
if
(mNitzTimeSetTime != NOT_SET && refTime - mNitzTimeSetTime < mPollingIntervalMs) {
resetAlarm(mPollingIntervalMs);
return
;
}
|
1
2
3
4
5
6
7
8
9
10
11
|
final
long
ntp = mTime.currentTimeMillis();
mTryAgainCounter =
0
;
// If the clock is more than N seconds off or this is the first time it's been
// fetched since boot, set the current time.
if
(Math.abs(ntp - currentTime) > mTimeErrorThresholdMs
|| mLastNtpFetchTime == NOT_SET) {
// Set the system time
......
if
(ntp /
1000
< Integer.MAX_VALUE) {
SystemClock.setCurrentTimeMillis(ntp);
}
|
当从时间服务器上获取的NTP时间和当前时间之差的绝对值大于一个阀值, 系统认为当前时间错误,需要更新时间。
总结:
如果时间自动同步选项未勾选,直接返回;
如果NITZ已同步且上次NITZ同步未超过24小时,则设置定时器24小时后再触发同步,即广播NetworkTimeUpdateService.ACTION_POLL;
如果NTP上次成功同步超过24小时或用户勾选自动同步选项,则进行下面的NTP同步,否则同上设置定时器24小时后再触发同步;
如果上次NTP成功同步超过24小时,则发起同步mTime.forceRefresh();
如果同步成功,获取此刻NTP时间ntp=mTime.currentTimeMillis();
如果同步时间与当前本机时间误差超过指定值阀值,则把ntp设置为本机时间SystemClock.setCurrentTimeMillis(ntp)
Android4.0 时间更新分析 NTPServer更改
frameworks\base\core\java\android\util\NtpTrustedTime.java
<!-- Remote server that can provide NTP responses. -->
<string translatable="false" name="config_ntpServer">2.android.pool.ntp.org</string>
验证方法:
mmm frameworks/base/core/res/
生成新的配置文件
out/target/product/godbox/system/framework/framework-res.apk
push framework-res.apk 到/system/framework/
备注:
网络的更新是通过上面的Java实现。如果系统没有时钟芯片,需要更改这个文件添加对待机广播报的处理
2.添加一个APK,专门用于时间更新(我比较喜欢这种),这样不会更改Google的Framework层代码,后期版本升级比较方便
Java的应用我是放在了packages/providers/NTPProvider。在应用调试中有几点需要注意
第一:注意APK的用户权限修改,和证书为platform
Android.mk中
LOCAL_CERTIFICATE := platform
AndroidManifest.xml
第二:注意Android4.0中系统服务不能直接调用网络通信接口,需要启动一个线程负责网络通信
启动方法:
210.72.145.44
203.117.180.36
131.107.1.10
time.asia.apple.com
64.236.96.53
130.149.17.21
66.92.68.246
www.freebsd.org
18.145.0.30
clock.via.net
137.92.140.80
133.100.9.2
128.118.46.3
ntp.nasa.gov
129.7.1.66ntp-sop.inria.frserver 210.72.145.44(中国国家授时中心服务器IP地址)