android4.4中自动更新时间机制
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
        publicvoidonChange(booleanselfChange) {
            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) {
         caseEVENT_AUTO_TIME_CHANGED:
         caseEVENT_POLL_NETWORK_TIME:
         caseEVENT_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


Review代码发现时间更新采用的服务器
    public static synchronized NtpTrustedTime getInstance(Context context) {
        if (sSingleton == null) {
            final Resources res = context.getResources();
            final ContentResolver resolver = context.getContentResolver();

            final String defaultServer = res.getString(
                    com.android.internal.R.string.config_ntpServer);
            final long defaultTimeout = res.getInteger(
                    com.android.internal.R.integer.config_ntpTimeout);

            final String secureServer = Settings.Secure.getString(
                    resolver, Settings.Secure.NTP_SERVER);
            final long timeout = Settings.Secure.getLong(
                    resolver, Settings.Secure.NTP_TIMEOUT, defaultTimeout);

            final String server = secureServer != null ? secureServer : defaultServer;
            sSingleton = new NtpTrustedTime(server, timeout);
        }

        return sSingleton;

NTP Server的地址来源与两个方面
1.用户设置Settings.Secure.NTP_SERVER
2.系统默认设置com.android.internal.R.string.config_ntpServer

所以更改方案两个方面
1.更新NTP的服务器:
更改文件
vim frameworks/base/core/res/res/values/config.xml

    <!-- 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/

adb connect 192.168.11.107
adb push out/target/product/godbox/system/framework/framework-res.apk /system/framework/


 

备注:

frameworks/base/services/java/com/android/server/NetworkTimeUpdateService.java


 

网络的更新是通过上面的Java实现。如果系统没有时钟芯片,需要更改这个文件添加对待机广播报的处理


 

2.添加一个APK,专门用于时间更新(我比较喜欢这种),这样不会更改Google的Framework层代码,后期版本升级比较方便

 Java的应用我是放在了packages/providers/NTPProvider。在应用调试中有几点需要注意

第一:注意APK的用户权限修改,和证书为platform

Android.mk中

LOCAL_CERTIFICATE := platform

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.providers.ntp"
    android:sharedUserId="android.uid.system"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />


 

第二:注意Android4.0中系统服务不能直接调用网络通信接口,需要启动一个线程负责网络通信

启动方法:

        public void SyncTime(){
Runnable syncTimeRunner = new Runnable() { 

                  @Override 
                  public void run() { 
                     SyncTimeLock(); 
                  } 
               }; 
               /* 启动线程负责网络通信 */
               new Thread(syncTimeRunner).start(); 
}

protected void SyncTimeLock(){
SntpClient client = new SntpClient();
for (int i = 0; i< setNtpServers.length; i++){
boolean flag = client.requestTime(setNtpServers[i], NTP_TIMEOUT);
Log.i(TAG, flag + " = client.requestTime(server:" + setNtpServers[i]+", timeout:"+NTP_TIMEOUT+")");
if(flag){
long now = client.getNtpTime() +SystemClock.elapsedRealtime()-client.getNtpTimeReference();
SystemClock.setCurrentTimeMillis(now);
Message msg = new Message();
msg.what = 1;
handeler.sendMessage(msg);
break;
}else if(i == setNtpServers.length-1){
Message msg = new Message();
msg.what = 0;
handeler.sendMessage(msg);
   }
}
}

133.100.11.8 prefer
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地址)
阅读更多
个人分类: android
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

android4.4中自动更新时间机制

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭