您的位置:首页 > 移动开发 > Android开发

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

2014-10-21 10:58 337 查看
名词解释:

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();

?
handler接到消息后进行消息处理调用onPollNetworkTime(msg.what),发现无论是数据或者是wifi下都是调用该方法进行更新

?
3.在onPollNetworkTime方法中先判断是否勾选“自动更新时间”,如果没勾选直接退出,如果勾选了再看,如果更新的NITZ时间不为NOT_SET(-1),且更新间隔小于mPollingIntervalMs,mPollingIntervalMs=24小时,那么就直接更新NITZ的时间,否则用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);
}
}
}

中国大概能用的NTP服务器地址

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地址)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: