两种时间更新机制

NITZ

NITZ(Network Identity and Time Zone,网络标识和时区),是一种用于自动配置本地的时间和日期的机制,同时也通过无线网向移动设备提供运营商信息。NITZ是自从PHASE 2+ RELEASE 96 的GSM中的可选功能,经常被用来自动更新移动电话的系统时钟。NITZ需要运营商网络支持(通过CS网络),目前国内电信、移动都支持NITZ方式更新时间日期,而联通目前不支持。

参考: https://en.wikipedia.org/wiki/NITZ

NTP

NTP:NTP(Network Time Protocol)提供准确时间,首先要有准确的时间来源,这一时间应该是国际标准时间UTC。 NTP获得UTC的时间来源可以是原子钟、天文台、卫星,也可以从Internet上获取。这样就有了准确而可靠的时间源。时间按NTP服务器的等级传播。与NITZ不同的是,NTP需要从专门的NTP服务器来获取时间,只要手机连接上网络,都可以实现时间的更新。

参考: https://en.wikipedia.org/wiki/Network_Time_Protocol

Android如何更新系统时间

Android有一个专门的系统服务 NetworkTimeUpdateServcie来负责更新系统时间,该服务在系统启动时在SystemServer.java中被创建:

    if (!disableNetwork && !disableNetworkTime) {try {Slog.i(TAG, "NetworkTimeUpdateService");networkTimeUpdater = new NetworkTimeUpdateService(context);} catch (Throwable e) {reportWtf("starting NetworkTimeUpdate service", e);}}......try {if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemRunning();} catch (Throwable e) {reportWtf("Notifying NetworkTimeService running", e);}

源码: /frameworks/base/services/core/java/com/android/server/NetworkTimeUpdateService.java

服务初始化

NetworkTimeUpdateService初始时会:

  • 注册RIL的ACTION_NETWORK_SET_TIME以及ACTION_NETWORK_SET_TIMEZONE事件,以接受来自Telephony FW的NITZ时间更新;
  • 监听 ACTION_POLL事件(定时更新时间)以及手机网络连接状态;
  • 发送消息同步NTP时间
  • 监听 Settings中“自动更新时间”选项的变化
    /** Initialize the receivers and initiate the first NTP request */public void systemRunning() {registerForTelephonyIntents();registerForAlarms();registerForConnectivityIntents();HandlerThread thread = new HandlerThread(TAG);thread.start();mHandler = new MyHandler(thread.getLooper());// Check the network time on the new threadmHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget();mSettingsObserver = new SettingsObserver(mHandler, EVENT_AUTO_TIME_CHANGED);mSettingsObserver.observe(mContext);}

同步NTP时间

如果没有收到NITZ时间的更新并且NTP超过一定间隔没有更新时间,服务会主动去同步NTP时间:

    // force refresh NTP cache when outdatedif (mTime.getCacheAge() >= mPollingIntervalMs) {mTime.forceRefresh();}

这里可能会出现问题,时区选对了,但是时间日期都不准确,这里原因NTPServer服务器配置不对

修改配置位置:frameworks\base\core\res\res\values\config.xml

关键参数config_ntpServer

可以参考一下

<!-- Remote server that can provide NTP responses. -->
    <string translatable="false" name="config_ntpServer">2.android.pool.ntp.org</string>
    <!-- Normal polling frequency in milliseconds -->
    <integer name="config_ntpPollingInterval">864000000</integer>
    <!-- Try-again polling interval in milliseconds, in case the network request failed -->
    <integer name="config_ntpPollingIntervalShorter">60000</integer>
    <!-- Number of times to try again with the shorter interval, before backing
         off until the normal polling interval. A value < 0 indicates infinite. -->
    <integer name="config_ntpRetry">3</integer>
    <!-- If the time difference is greater than this threshold in milliseconds,
         then update the time. -->
    <integer name="config_ntpThreshold">5000</integer>
    <!-- Timeout to wait for NTP server response. -->
    <integer name="config_ntpTimeout">20000</integer>

NTP从服务器获取时间:

    @Overridepublic boolean forceRefresh() {...// We can't do this at initialization time: ConnectivityService might not be running yet.synchronized (this) {if (mCM == null) {mCM = (ConnectivityManager) sContext.getSystemService(Context.CONNECTIVITY_SERVICE);}}...if (LOGD) Log.d(TAG, "forceRefresh() from cache miss");final SntpClient client = new SntpClient();if (client.requestTime(mServer, (int) mTimeout)) {mHasCache = true;mCachedNtpTime = client.getNtpTime();mCachedNtpElapsedRealtime = client.getNtpTimeReference();mCachedNtpCertainty = client.getRoundTripTime() / 2;return true;} else {return false;}}

源码: /frameworks/base/core/java/android/util/NtpTrustedTime.java

接收NITZ时间

Telephony Framework层在接收到最新的NITZ时间后,会主动发送广播请求更新系统时间,NetworkTimeUpateService接收到广播后,保存相应的NITZ时间,下一次poll请求时,就会将该事件更新为系统时间。

    private BroadcastReceiver mNitzReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (TelephonyIntents.ACTION_NETWORK_SET_TIME.equals(action)) {mNitzTimeSetTime = SystemClock.elapsedRealtime();} else if (TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE.equals(action)) {mNitzZoneSetTime = SystemClock.elapsedRealtime();}}};

监听Settings中 “自动确定时间和日期”的变化

在setting中勾选“自动确定时间和日期”、“自动确定时区”后对key值为AUTO_TIME和AUTO_TIME_ZONE的Preference进行了赋值.

源码路径:packages/apps/Settings/src/com/android/settings/DateTimeSettings.java

    void observe(Context context) {ContentResolver resolver = context.getContentResolver();resolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.AUTO_TIME),false, this);}@Overridepublic void onChange(boolean selfChange) {mHandler.obtainMessage(mMsg).sendToTarget();}

NetworkTimeUpdateService在检测到key值改变的时,就会发送一个消息EVENT_AUTO_TIME_CHANGED;handler接到消息后进行消息处理调用onPollNetworkTime(msg.what):

    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;}}

在onPollNetworkTime方法中先判断是否勾选“自动更新时间”,如果没勾选直接退出,如果勾选了再看。如果NITZ已经更新了(不为NOT_SET(-1)),且更新间隔小于mPollingIntervalMs(mPollingIntervalMs=24*60*60*1000),则直接用NITZ更新系统时间,否则用NTP同步时间。

    // 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;}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小时后再触发同步

参考文献

  • http://www.2cto.com/kf/201409/334153.html
  • http://blog.csdn.net/lindir/article/details/7973700
  • https://en.wikipedia.org/wiki/NITZ
  • https://en.wikipedia.org/wiki/Network_Time_Protocol

Android 系统时间自动更新机制--解决 “时间和日期不准确“相关推荐

  1. Android 系统时间自动更新机制

    两种时间更新机制 NITZ NITZ(Network Identity and Time Zone,网络标识和时区),是一种用于自动配置本地的时间和日期的机制,同时也通过无线网向移动设备提供运营商信息 ...

  2. win7系统的自动更新很长时间,如何关闭

    点击计算机左下角开始菜单,找到控制面板,点击打开 选择 系统安全,点击打开 点击 Windows Update 打开 左边栏选择 更改设置 打开 选择下拉栏 选择 除了"自动更新(推荐)&q ...

  3. 主板没电 自动更新计算机时间,笔记本电脑系统时间不更新怎么样解决

    windows7系统增加了一项自动与Internet时间服务器同步的功能.对于联了网的用户可以开启此功能,这样,计算机系统时钟每隔一周就会与Internet时间服务器进行一次同步,从而保证系统时间的准 ...

  4. Android9.0 本地时区和本地时间的自动更新机制

    Android9.0 本地时区和本地时间的自动更新机制 简介 现在Android通过网络同步时间有两种方式:NITZ和NTP,它们使用的条件不同,可以获取的信息也不一样:勾选自动同步功能后,手机首先会 ...

  5. Mysql 添加 create_time, update_time 创建时间 更新时间 自动更新

    # 添加 创建 更新 时间字段 ALTER TABLE `表名` ADD COLUMN `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAM ...

  6. Android Studio 自动更新失败解决办法

    Android Studio 自动更新失败解决办法 Dec 26th, 2014 | Comments 昨天在G+中看到Android Studio又有更新了就心血来潮想去更新体验一下,可是无论我怎么 ...

  7. 在网页中插入时间 自动更新

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  8. 向mysql中添加更新时间_mysql 实现添加时间自动添加更新时间自动更新操作

    在数据库使用中经常使用到时间字段.常用的有创建时间和更新时间. 然而在使用中想要创建时间在创建的时候自动设置为当前时间,更新时间在更新时自动更新为当前时间. 创建表 stu CREATE TABLE ...

  9. 更新域内计算机时间,Word2013如何自动更新文档中的日期和时间?如何设置打印前自动更新域...

    在Word2013文档中插入日期和时间,如何实现自动更新,下面小编就给大家介绍一下Word2013中自动更新文档中的日期和时间的方法,而且,使用这个办法还可以插入会自动更新的时间,最后,还给大家分享了 ...

最新文章

  1. python array 语法_Python基本语法
  2. 【jsp】页面跳转的两种方法
  3. xor java_java基于密匙的xor加解密
  4. 使用split进行分割时遇到特殊字符的问题
  5. Spring的核心思想,总结得非常好!
  6. frps与frpc的区别
  7. java 重用性_Java开发重用性必备的三大核心知识点
  8. vue图片加载失败使用默认图片,el-image支持懒加载,自定义占位、加载失败等
  9. Java基础学习总结(147)——Java常用分布式锁技术方案
  10. 更改多个版本java_window下在同一台机器上安装多个版本jdk,修改环境变量不生效问题处理办法...
  11. 关于DTC诊断故障码的获取与清除(ISO14229系列之14、19服务)
  12. 海康sip服务器是什么意思_海康摄像头入门
  13. 李想:“做正确的事,不做容易的事”
  14. centos7 rpm安装时报警 Header V3 RSA/SHA256 Signature, key ID 352c64e5: NOKEY
  15. mysql数据库压缩_Mysql压缩解决方案
  16. android 获取系统是否允许自动旋转屏幕
  17. Dart基础之Isolate
  18. 【转载】自然语言处理(NLP)的历史、发展、成果和难题,以及在教育领域的应用情况
  19. 读薄《高性能MySql》(三)索引优化
  20. 第四届高教杯计算机绘图教程,第三届“高教杯”机械类计算机绘图试卷(三维).pdf...

热门文章

  1. GOM登录器配置免费生成图文教程
  2. linux怎么找宝塔地址,宝塔Linux面板安全入口地址忘了(方法一)
  3. (附源码)springboot学生社团管理系统 毕业设计 151109
  4. CAS单点登录(http方式)
  5. line-height行高
  6. java通过poi读取excel中的日期类型
  7. sublime text3入门教程
  8. python画饼图程序_Scribus中的Python脚本:制作饼图
  9. 绝了,SpringBoot引入 Dataway,无需开发任何代码配置一个满足需求的接口!
  10. 【转贴】对《高质量程序设计指南--C++/C第二版》的探讨