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


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地址)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值