MTK NTP和NITZ更新时间的问题
NITZ(Network Identity and Time Zone,网络标识和时区),是一种用于自动配置本地的时间和日期的机制,同时也通过无线网向移动设备提供运营商信息。NITZ是自从PHASE 2+ RELEASE 96 的GSM中的可选功能,经常被用来自动更新移动电话的系统时钟。NITZ需要运营商网络支持(通过CS网络),目前国内电信、移动都支持NITZ方式更新时间日期,而联通目前不支持。
一。配置服务器端:
那么比如在英国的话就可以选择下面两个服务器
.uk.pool.ntp.org
.uk.pool.ntp.org
它的一般格式都是number.country.pool.ntp.org
中国的ntp服务器地址:
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 (国家授时中心服务器IP地址)
二。修改默认NTP配置
1.通过SntpClient.java来封装请求。
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[] = NTP_MODE_CLIENT | (NTP_VERSION << );
// 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))/;
// 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.发起同步的,这个方法的主角为:NtpTrustedTime.java 在该类中通过forceRefresh方法来更新获取服务器时间。
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() / ;
return true;
} else {
return false;
}
}
3.时间同步请求处理逻辑。在onPollNetworkTime方法中进行同步处理。
/frameworks/base/services/core/java/com/android/server/NetworkTimeUpdateService.java
private void onPollNetworkTime(int event) {
//1、是否勾选自动同步时间配置
// If Automatic time is not set, don't bother.
if (!isAutomaticTimeRequested()) return;
//2、mNitzTimeSetTime 来自Moderm,如果当前时间刚通过moderm更新不久,则不进行时间同步。
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、如果机器刚启动,或者机器运行时间大于mPollingIntervalMs,即10天,或者设置等发起的主动更新时间请求,则发起网络时间同步请求。否则,10天后再进行时间同步。
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、是否含有时间缓冲,如无,发起时间同步,
// 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、遍历时间服务器,发起时间同步
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、获取最新同步的时间缓冲数据,如无,则再次发起时间同步,间隔时间为mPollingIntervalShorterMs,即30秒。
// only update when NTP time is fresh
if (mTime.getCacheAge() < mPollingIntervalMs) {
final long ntp = mTime.currentTimeMillis();
mTryAgainCounter = ;
// 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、如果开机第一次同步或者最新时间与当前时间差别超过mTimeErrorThresholdMs即25秒,则进行时间设定。否则认定新同步时间与当前时间差别不大,不覆盖当前时间。
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、设定同步时间
if (ntp / < 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 如果不大于最大同步次数,30秒后进行时间同步,否则,10天后更新。
mTryAgainCounter++;
if (mTryAgainTimesMax < || mTryAgainCounter <= mTryAgainTimesMax) {
resetAlarm(mPollingIntervalShorterMs);
} else {
// Try much later
mTryAgainCounter = ;
resetAlarm(mPollingIntervalMs);
}
return;
}
}
//4、如果刚更新时间不久,则10天后再发起时间同步请求。
resetAlarm(mPollingIntervalMs);
}
4.减小NTP请求的时间,确保开机联网立即同步时间
/frameworks/base/core/res/res/values/config.xml
<integer name="config_ntpPollingIntervalShorter"></integer>
MTK NTP和NITZ更新时间的问题的更多相关文章
- Linux NTP服务器的搭建及client自动更新时间
Network Time Protocol(NTP)是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)做同步化,它可以提供高精准度的时间校正(LAN上与标准间 ...
- Linux下更新时间
方法一.使用命令 ntpdate time-a.nist.gov 方法二.本地安装ntpdate客户端 在本地安装ntpdate客户端,更新时用 ntpdate cn.pool.ntp.org 如果你 ...
- Ubuntu 16 , 从时间服务器更新时间
因为在公司的内网,所以不能用Ubuntu默认的服务器去更新时间. 只能改成从网关 10.182.202.2 上取时间 1) 如果没有安装ntp 的话,先安装 apt-get install ntp 2 ...
- 通过自定义特性,使用EF6拦截器完成创建人、创建时间、更新人、更新时间的统一赋值(使用数据库服务器时间赋值,接上一篇)
目录: 前言 设计(完成扩展) 实现效果 扩展设计方案 扩展后代码结构 集思广益(问题) 前言: 在上一篇文章我写了如何重建IDbCommandTreeInterceptor来实现创建人.创建时间.更 ...
- 自动化部署与统一安装升级 - 类ansible工具 udeploy0.3版本发布 (更新时间2014-12-24)
下载地址: unifyDeploy0.1版本 unifyDeploy0.2版本 unifyDeploy0.3版本 (更新时间2014-07-25) 自动化部署与统一安装升级,适用于多资 ...
- [转]Hibernate设置时间戳的默认值和更新时间的自动更新
原文地址:http://blog.csdn.net/sushengmiyan/article/details/50360451 Generated and default property value ...
- ubuntu server设置时区和更新时间
ubuntu server设置时区和更新时间 今天测试时,发现时间不对,查了一下时区: data -R 结果时区是:+0000 我需要的是东八区,这儿显示不是,所以需要设置一个时区 一.运行 ...
- Oracle数据库更新时间的SQL语句
---Oracle数据库更新时间字段数据时的sql语句---格式化时间插入update t_user u set u.name='pipi',u.modifytime=to_date('2015-10 ...
- mysql table 最新更新时间
查看表的最后mysql修改时间 SELECT TABLE_NAME,UPDATE_TIME FROM information_schema.tables where TABLE_SCHEMA='d ...
随机推荐
- HDFS JournalNode 故障
背景 某天凌晨四点左右,HBase RegionServer 宕机自动拉起,查看日志发现是HDFS 在进行HA切换,15次重试仍连不上可写的active,于是挂了.所以根本问题是hdfs. 日志定位 ...
- 【LCA】求和VII @北京OI2018
目录 求和VII PROBLEM 题目描述 输入 输出 样例输入 样例输出 提示 SOLUTION CODE 求和VII PROBLEM 时间限制: 2 Sec 内存限制: 256 MB 题目描述 m ...
- delphi TTBXToolBar 增加外部控件
这样可以引用外部控件,还是比较方便
- 使用linux kernel代码编译perf工具
环境:Qemu + ARMv8 perf是一款综合性分析工具,大到系统全局性性能,再小到进程线程级别,甚至到函数及汇编级别. 在内核源码目录下执行编译脚本: #!/bin/bash cross_com ...
- Android如何实现茄子快传
Android如何实现茄子快传茄子快传是一款文件传输应用,相信大家都很熟悉这款应用,应该很多人用过用来文件的传输.它有两个核心的功能: 端到端的文件传输Web端的文件传输这两个核心的功能我们具体来分析 ...
- Coursera机器学习+deeplearning.ai+斯坦福CS231n
日志 20170410 Coursera机器学习 2017.11.28 update deeplearning 台大的机器学习课程:台湾大学林轩田和李宏毅机器学习课程 Coursera机器学习 Wee ...
- android:第十章,后台的默默劳动者——服务,学习笔记
一.多线程 1)本章首先介绍了安卓的多线程编程,说明在子线程中如果要修改UI,必须通过Handler, Message, MessageQueue, Looper来实现,但是这样毕竟太麻烦了. 2) ...
- ImportError: No module named _tkinter on macos
MAC OS 10.11.6 lMacBook-Pro:~ xiaomilbq$ python Python 2.7.14 (default, Sep 22 2017, 00:05:22) [GCC ...
- ASM ClassReader failed to parse class file解决方法
1. 环境信息: Spring 3.2.2, JDK 1.8, Hibernate 3.5.5 2. 运行简单的程序,出现以下错误信息: [2018-05-25 02:36:58,671] Ar ...
- Spring Boot用Cxf的jax-ws开发WebService
首先上项目的pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&q ...