MTK NTP和NITZ更新时间的问题
NITZ(Network Identity and Time Zone,網(wǎng)絡(luò)標(biāo)識(shí)和時(shí)區(qū)),是一種用于自動(dòng)配置本地的時(shí)間和日期的機(jī)制,同時(shí)也通過(guò)無(wú)線網(wǎng)向移動(dòng)設(shè)備提供運(yùn)營(yíng)商信息。NITZ是自從PHASE 2+ RELEASE 96 的GSM中的可選功能,經(jīng)常被用來(lái)自動(dòng)更新移動(dòng)電話的系統(tǒng)時(shí)鐘。NITZ需要運(yùn)營(yíng)商網(wǎng)絡(luò)支持(通過(guò)CS網(wǎng)絡(luò)),目前國(guó)內(nèi)電信、移動(dòng)都支持NITZ方式更新時(shí)間日期,而聯(lián)通目前不支持。
一。配置服務(wù)器端:
那么比如在英國(guó)的話就可以選擇下面兩個(gè)服務(wù)器
0.uk.pool.ntp.org 1.uk.pool.ntp.org
它的一般格式都是number.country.pool.ntp.org
中國(guó)的ntp服務(wù)器地址:
server 133.100.11.8 prefer server 210.72.145.44 server 203.117.180.36 server 131.107.1.10 server time.asia.apple.com server 64.236.96.53 server 130.149.17.21 server 66.92.68.246 server www.freebsd.org server 18.145.0.30 server clock.via.net server 137.92.140.80 server 133.100.9.2 server 128.118.46.3 server ntp.nasa.gov server 129.7.1.66 server ntp-sop.inria.fr server (國(guó)家授時(shí)中心服務(wù)器IP地址)
二。修改默認(rèn)NTP配置
1.通過(guò)SntpClient.java來(lái)封裝請(qǐng)求。
frameworks/base/core/java/android/net/SntpClient.java
public boolean requestTime(String host, int timeout) {
DatagramSocket socket = null;
try {
socket = new DatagramSocket();
socket.setSoTimeout(timeout);
InetAddress address = InetAddress.getByName(host);
byte[] buffer = new byte[NTP_PACKET_SIZE];
DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, NTP_PORT);
// set mode = 3 (client) and version = 3
// mode is in low 3 bits of first byte
// version is in bits 3-5 of first byte
buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3);
// get current time and write it to the request packet
long requestTime = System.currentTimeMillis();
long requestTicks = SystemClock.elapsedRealtime();
writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET, requestTime);
socket.send(request);
// read the response
DatagramPacket response = new DatagramPacket(buffer, buffer.length);
socket.receive(response);
long responseTicks = SystemClock.elapsedRealtime();
long responseTime = requestTime + (responseTicks - requestTicks);
// extract the results
long originateTime = readTimeStamp(buffer, ORIGINATE_TIME_OFFSET);
long receiveTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET);
long transmitTime = readTimeStamp(buffer, TRANSMIT_TIME_OFFSET);
long roundTripTime = responseTicks - requestTicks - (transmitTime - receiveTime);
// receiveTime = originateTime + transit + skew
// responseTime = transmitTime + transit - skew
// clockOffset = ((receiveTime - originateTime) + (transmitTime - responseTime))/2
// = ((originateTime + transit + skew - originateTime) +
// (transmitTime - (transmitTime + transit - skew)))/2
// = ((transit + skew) + (transmitTime - transmitTime - transit + skew))/2
// = (transit + skew - transit + skew)/2
// = (2 * skew)/2 = skew
long clockOffset = ((receiveTime - originateTime) + (transmitTime - responseTime))/2;
// if (false) Log.d(TAG, round trip: + roundTripTime + ms);
// if (false) Log.d(TAG, clock offset: + clockOffset + ms);
// save our results - use the times on this side of the network latency
// (response rather than request time)
mNtpTime = responseTime + clockOffset;
mNtpTimeReference = responseTicks;
mRoundTripTime = roundTripTime;
} catch (Exception e) {
if (false) Log.d(TAG, request time failed: + e);
return false;
} finally {
if (socket != null) {
socket.close();
}
}
return true;
}
2.發(fā)起同步的,這個(gè)方法的主角為:NtpTrustedTime.java 在該類(lèi)中通過(guò)forceRefresh方法來(lái)更新獲取服務(wù)器時(shí)間。
frameworks/base/core/java/android/util/NtpTrustedTime.java
public boolean forceRefresh() {
if (mServer == null) {
// missing server, so no trusted time available
return false;
}
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;
}
}
3.時(shí)間同步請(qǐng)求處理邏輯。在onPollNetworkTime方法中進(jìn)行同步處理。
/frameworks/base/services/core/java/com/android/server/NetworkTimeUpdateService.java
private void onPollNetworkTime(int event) {
//1、是否勾選自動(dòng)同步時(shí)間配置
// If Automatic time is not set, don't bother.
if (!isAutomaticTimeRequested()) return;
//2、mNitzTimeSetTime 來(lái)自Moderm,如果當(dāng)前時(shí)間剛通過(guò)moderm更新不久,則不進(jìn)行時(shí)間同步。
final long refTime = SystemClock.elapsedRealtime();
// 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;
}
//3、如果機(jī)器剛啟動(dòng),或者機(jī)器運(yùn)行時(shí)間大于mPollingIntervalMs,即10天,或者設(shè)置等發(fā)起的主動(dòng)更新時(shí)間請(qǐng)求,則發(fā)起網(wǎng)絡(luò)時(shí)間同步請(qǐng)求。否則,10天后再進(jìn)行時(shí)間同步。
final long currentTime = System.currentTimeMillis();
if (DBG) Log.d(TAG, System time = + currentTime);
// Get the NTP time
if (mLastNtpFetchTime == NOT_SET || refTime >= mLastNtpFetchTime + mPollingIntervalMs
|| event == EVENT_AUTO_TIME_CHANGED) {
if (DBG) Log.d(TAG, Before Ntp fetch);
//3.1、是否含有時(shí)間緩沖,如無(wú),發(fā)起時(shí)間同步,
// force refresh NTP cache when outdated
if (mTime.getCacheAge() >= mPollingIntervalMs) {
//LEUI-START [BUG][MOBILEP-6067] [System time sync added
//mTime.forceRefresh();
int index = mTryAgainCounter % mNtpServers.size();
if (DBG) Log.d(TAG, mTryAgainCounter = + mTryAgainCounter + ;mNtpServers.size() = + mNtpServers.size() + ;index = + index + ;mNtpServers = + mNtpServers.get(index));
//3.1.1、遍歷時(shí)間服務(wù)器,發(fā)起時(shí)間同步
if (mTime instanceof NtpTrustedTime)
{
((NtpTrustedTime) mTime).setServer(mNtpServers.get(index));
mTime.forceRefresh();
((NtpTrustedTime) mTime).setServer(mDefaultServer);
}
else
{
mTime.forceRefresh();
}
//LEUI-END [BUG][MOBILEP-6067] [System time sync added
}
//3.2、獲取最新同步的時(shí)間緩沖數(shù)據(jù),如無(wú),則再次發(fā)起時(shí)間同步,間隔時(shí)間為mPollingIntervalShorterMs,即30秒。
// only update when NTP time is fresh
if (mTime.getCacheAge() < mPollingIntervalMs) {
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.
//3.2.1、如果開(kāi)機(jī)第一次同步或者最新時(shí)間與當(dāng)前時(shí)間差別超過(guò)mTimeErrorThresholdMs即25秒,則進(jìn)行時(shí)間設(shè)定。否則認(rèn)定新同步時(shí)間與當(dāng)前時(shí)間差別不大,不覆蓋當(dāng)前時(shí)間。
if (Math.abs(ntp - currentTime) > mTimeErrorThresholdMs
|| mLastNtpFetchTime == NOT_SET) {
// Set the system time
if (DBG && mLastNtpFetchTime == NOT_SET
&& Math.abs(ntp - currentTime) <= mTimeErrorThresholdMs) {
Log.d(TAG, For initial setup, rtc = + currentTime);
}
if (DBG) Log.d(TAG, Ntp time to be set = + ntp);
// Make sure we don't overflow, since it's going to be converted to an int
//3.2.2、設(shè)定同步時(shí)間
if (ntp / 1000 < Integer.MAX_VALUE) {
SystemClock.setCurrentTimeMillis(ntp);
}
} else {
if (DBG) Log.d(TAG, Ntp time is close enough = + ntp);
}
mLastNtpFetchTime = SystemClock.elapsedRealtime();
} else {
// Try again shortly
//3.3 如果不大于最大同步次數(shù),30秒后進(jìn)行時(shí)間同步,否則,10天后更新。
mTryAgainCounter++;
if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) {
resetAlarm(mPollingIntervalShorterMs);
} else {
// Try much later
mTryAgainCounter = 0;
resetAlarm(mPollingIntervalMs);
}
return;
}
}
//4、如果剛更新時(shí)間不久,則10天后再發(fā)起時(shí)間同步請(qǐng)求。
resetAlarm(mPollingIntervalMs);
}
4.減小NTP請(qǐng)求的時(shí)間,確保開(kāi)機(jī)聯(lián)網(wǎng)立即同步時(shí)間
/frameworks/base/core/res/res/values/config.xml
<integer name="config_ntpPollingIntervalShorter">10000</integer>
總結(jié)
以上是生活随笔為你收集整理的MTK NTP和NITZ更新时间的问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Ubuntu下安装cmake,配置ITK
- 下一篇: Ubuntu下安装 imagej 和 F