目录
一 概述
二 NITZ
NITZ时间设置流程示意图
三 NTP
NTP时间设置流程示意图
四 总结
一 概述
android系统支持时间的手动设置与自动设置。如果选择自动时间设置,系统会根据获取的运营商网络的NITZ信息或同ntp服务器获取的utc时间对系统时间进行设置。android系统时间设置以NITZ时间为主,NTP时间为辅。下面分别介绍一下这两种时间获取方式。
二 NITZ
下面是对NITZ的介绍,很精简直接上英文不做翻译了。
NITZ (Network Identity and Time Zone) is a mechanism for provisioning local time and date, time zone and daylight saving time(DST) offset, as well as network provider identity information, to mobile devices via a wireless network. NITZ is often used to automatically update the system clock and carrier name of mobile phones.
运营商通过在NAS层信令中的MM INFORMATION & GMM INFORMATION消息中携带NITZ信息传递给终端,一般发生在location update, CM service request, attach , routing area upate 过程之后。网络是否会发送NITZ信息取决于运营商网络的配置。
对android设备来说,首先是modem收到信令,解析出NITZ信息通过RIL(RIL_UNSOL_NITZ_TIME_RECEIVED)传递给Telephony。接下来的处理android10与之前的版本会略有不同。
Android 10之前的版本,Telephony中的ServiceStateTracker模块收到NITZ后通过调用AlarmManager API进行时间或时区的设置,并发送广播android.intent.action.NETWORK_SET_TIME 或 android.intent.action.NETWORK_SET_TIMEZONE。
Android 10版本,Telephony中的ServiceStateTracker模块收到后NITZ后,把信息传递给系统服务TimeDetectorService,在TimeDetectorService中调用AlarmManager对时间进行设置,并发送广播android.intent.action.NETWORK_SET_TIME或。而时区是在Telephony中完成设置的,之后发送广播android.intent.action.NETWORK_SET_TIMEZONE。
- public void AlarmManager.setTime(long millis),最终通过JNI,调用linux C函数settimeofday()对系统时间进行设置,并通过ioctrl操作设备结点/dev/rtc0来进行rtc时间设置。
注意:高通平台上默认禁掉了APSS设置rtc的权限,只能MPSS可以设置
- public void setTimeZone(String timeZone), 最终把timezone设置到系统属性persist.sys.timezone中
NITZ时间设置流程示意图
下图为NITZ时间设置的流程示意图,图画的不是很规范,主要为说明大致流程。
三 NTP
NTP(Network Time Protocol,网络时间协议)是由RFC 1305定义的时间同步协议,用来在分布式时间服务器和客户端之间进行时间同步。NTP基于UDP报文进行传输,使用的UDP端口号为123。使用NTP的目的是对网络内所有具有时钟的设备进行时钟同步,使网络内所有设备的时钟保持一致,从而使设备能够提供基于统一时间的多种应用。对于运行NTP的本地系统,既可以接收来自其他时钟源的同步,又可以作为时钟源同步其他的时钟,并且可以和其他设备互相同步。
注意: NTP可以同步时间但不能同步时区。
android系统中有个系统服务NetworkTimeUpdateService,开机初始化时在system_server中启动,负责ntp时间的自动更新。所在文件为frameworks/base/services/core/java/com/android/server/NetworkTimeUpdateService.java。
在 frameworks/base/core/res/res/values/config.xml 文件中有对ntp服务的一些设置。
NetworkTimeUpdateService服务启动后,会监测以下三个事件:
- 开启时间自动设置
- 时间同步周期到达
- 网络变为连接状态
当任意事件到达,都会触发ntp时间同步流程,时间同步流程发起前会做一些判断,来决定是否有必要发起时间同步,时间同步是在单独handler线程中执行的。
/** Initialize the receivers and initiate the first NTP request */
public void systemRunning() {
registerForTelephonyIntents();
registerForAlarms();
HandlerThread thread = new HandlerThread(TAG);
thread.start();
mHandler = new MyHandler(thread.getLooper());
mNetworkTimeUpdateCallback = new NetworkTimeUpdateCallback();
mCM.registerDefaultNetworkCallback(mNetworkTimeUpdateCallback, mHandler);
mSettingsObserver = new SettingsObserver(mHandler, EVENT_AUTO_TIME_CHANGED);
mSettingsObserver.observe(mContext);
}
/** Handler to do the network accesses on */
private class MyHandler extends Handler {
public MyHandler(Looper l) {
super(l);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case EVENT_AUTO_TIME_CHANGED:
case EVENT_POLL_NETWORK_TIME:
case EVENT_NETWORK_CHANGED:
onPollNetworkTime(msg.what);
break;
}
}
}
NTP时间设置流程示意图
ntp时间获取之前会做一些判断,主要就是判断最近一段时间内是否进行过NITZ或是ntp时间同步,系统时间与NTP服务器的时间误差是否大于某个门限值,来决定是否现在就进行ntp系统时间设置。
四 总结
android系统自动时间设置主要是根据运营商的NITZ时间以及ntp服务器时间进行设置,以NITZ时间为主。NITZ可以同步时间与时区,ntp只能同步时间。GPS同样可以获取时间与时区,但目前android系统中默认时间设置没有使用gps的信息。另外局域网之间的时间同步会用到gPTP(general precise time protocol)协议基于层二传输(MAC),后面对这块了解了再补充进来。