Android 校正系统时间的三种解决方案

前言
在开发过程中我们常常需要获取系统时间。
Android系统的自动确认时间,是由系统通过访问厂家的NTP服务器的时间,然后修改后得到的。
所以当没有网络或者在内网环境下的时候,系统无法访问到NTP服务器,便会造成系统时间错误。
所以这个时候我们就需要程序去修改系统的时间,或者获取一个正确的时间来代替系统时间。

NTP服务器
【Network Time Protocol(NTP)】是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)做同步化,它可以提供高精准度的时间校正(LAN上与标准间差小于1毫秒,WAN上几十毫秒),且可介由加密确认的方式来防止恶毒的协议攻击。时间按NTP服务器的等级传播。按照离外部UTC源的远近把所有服务器归入不同的Stratum(层)中。

解决方案
根据不同的情况,我实现了如下三种解决方案:

修改系统时间。
优点:程序启动时执行一次即可,一劳永逸。
缺点:只能在原生系统中使用,非原生系统无法安装。(具体后面会解释)。

获取NTP服务器时间代替系统时间。
优点:无需Root,适用于任何手机及系统。
缺点:需要可以访问外部网络,内网环境下则需要一台自己的NTP服务器。

获取网页时间代替系统时间。
优点:无需Root,适用于任何手机及系统,适用于任何网络环境。
缺点:需要一条额外的线程,去维护时间准确,容易造成误差。

代码及目录

%title插图%num

1.修改系统时间
1.配置系统JDK环境变量
这个就不细说了,自行百度。
由于签名工具用到的sun.misc.BASE64Encoder类已从Java SE 9中删除。所以只能在Java 1.8及以下环境下使用。
具体可以查看:JDK从1.8升级到9.0.1后sun.misc.BASE64Decoder和sun.misc.BASE64Encoder不可用

2.修改系统时间,一行代码如下:
SystemClock.setCurrentTimeMillis(long millis);
1
3.修改AndroidManifest.xml
在应用程序的AndroidManifest.xml中的manifest节点中加入android:sharedUserId=”android.uid.system”这个属性。
添加该属性后,由于权限冲突,程序无法直接安装,必须重新签名。

<?xml version=”1.0″ encoding=”utf-8″?>
<manifest xmlns:android=”http://schemas.android.com/apk/res/android”
package=”com.demon.setsystemtime”
android:sharedUserId=”android.uid.system” >
</manifest>

4.编译apk,重新签名
Android Studio编译生成apk,然后将apk复制到上述目录的sign文件夹(重新签名的文件夹)下,将apk的名字与bat脚本中的一致。
用压缩软件打开apk文件,删掉META-INF目录下的CERT.SF和CERT.RSA两个文件。
双击运行bat脚本,脚本代码如下:

@echo off
java -jar signapk.jar platform.x509.pem platform.pk8 demo.apk test.apk
pause

signapk.jar: Android提供的签名工具。
platform.x509.pem&platform.pk8: Android源码目录中”build/target/product/security”,下面的两个文件。
demo.apk:程序编译生成的apk。
test.apk:重新签名后的apk。

这也有一个问题,就是这样生成的程序只有在原始的Android系统或者是自己编译的系统中才可以用,因为这样的系统才可以拿到platform.pk8和platform.x509.pem两个文件。要是别家公司做的Android上连安装都安装不了。

安装重新签名的apk,运行即可修改系统时间。

获取NTP服务器时间代替系统时间
直接使用truetime-android框架即可同步NTP服务器时间,调取框架内的方法便可以实时获取*新时间。
GitHub:https://github.com/instacart/truetime-android
具体的使用可以参考代码,或者GitHub文档。

### 阿里云提供了7个NTP服务器
ntp1.aliyun.com
ntp2.aliyun.com
ntp3.aliyun.com
ntp4.aliyun.com
ntp5.aliyun.com
ntp6.aliyun.com
ntp7.aliyun.com

### 中国科学技术大学NTP服务器
time.ustc.edu.cn

获取网页时间代替系统时间
根据下列代码,我们就可以获取任何一个网址的时间(内网服务器地址)。
拿到这个时间后,可以开启一个线程,做定时任务,不断更新该时间,以到达时间时间同步的效果。
具体实现方法不再阐述。

/**
* 网址访问
* @param url 网址
* @return urlDate 对象网址时间
*/
public static String VisitURL(String url){
String urlDate = null;
try {
URL url1 = new URL(url);
URLConnection conn = url1.openConnection(); //生成连接对象
conn.connect(); //连接对象网页
Date date = new Date(conn.getDate()); //获取对象网址时间
SimpleDateFormat df = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”); //设置日期格式
urlDate = df.format(date);
} catch (Exception e) {
e.printStackTrace();
}
return urlDate;
}

效果

%title插图%num

局域网配置NTP服务器

我们在做工程中经常发现PC、摄像机、UPS等设备都有NTP时间这个选项,与此同时不配置的话,回经常发现时间不是统一,就如我们调出录像时发现有的时间段不统一,于是将其Server2003的NTP服务开启,客户端于此同步即可!!!

默认情况下,windows server 2003在非域控制器的情况只作为NTP的客户端工作,同时默认是与time.windows.com同步,于是通过windows自带的W32Time服务器配置NTP服务器,并需通过设定客户端来与服务器同步时间。

一、NTP服务器架设

1、运行regedit,打开注册表,修改键值HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time \TimeProviders\NtpServer内的Enabled设定为1,目的主要是启用NTP服务器的功能

2、将W32Time \Config\AnnounceFlags设定为5,目的是强制主机将其自身宣布为可靠的时间源(如果要使用Internet上的时间服务器,需要设定为默认a)

3、重启w32time服务

运行cmd,进入命令行界面输入

net stop w32time(停止w32time服务) ,

net start w32time(重启W32time服务)

4、到此为止我们的W32time服务器架设好了,接下了我们设置客户端同步。

二、NTP客户端设置及其同步

1、进入注册表修改

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpClient下的

SpecialPollInterval 值修改成十进制43200 (单位为秒,43200为12小时,该时间是客户端与服务器时间同步的间隔)

SpecialPollTimeRemaining 值修改成[时间同步服务器],0 如:192.168.3.101,0

2、到此为止客户端设定完成,可通过命令立即更新客户端时间,

w32tm /resync /nowait

也可以通过点击右下角时间,弹出【日期和时间】,点击Internet时间选项卡,选择更改设置,将其服务器192.168.3.101,点击立即更新!

注意:由于w32time服务使用的是123端口来同步时间,所以,还需要开通NTP服务连接外网的TCP和UDP的123端口

配置Windows为NTP服务器

建议使用 ntpd for windows,这是一个ntp的windows版,操作和linux相似

下载:https://www.meinbergglobal.com/english/sw/ntp.htm#ntp_nt

目前版本是ntp-4.2.8p7,经测试可以在win7上使用。

1、下载安装,都很简单,下一步完成。

2、配置,基本和linux差不多,安装应用目录

%title插图%num

点击Edit Ntp Configuration,进行ntp配置,参考linux配置

#默认拒*所有来源的任何访问
restrict default noquery nopeer nomodify notrap  
restrict -6 default noquery nopeer nomodify notrap  
 
# allow status queries and everything else from localhost 
# 允许本地访问
restrict 127.0.0.1 
restrict -6 ::1 

# if you need to allow access from a remote host, you can add lines like this: 
# restrict <IP OF REMOTE HOST> 
# 设置自己需要访问的网段地址
restrict 10.102.145.0 mask 255.255.255.0 nomodify
restrict 10.20.0.0 mask 255.255.0.0 nomodify

# Use drift file 
driftfile "C:\Program Files (x86)\NTP\etc\ntp.drift"

# your local system clock, could be used as a backup
# (this is only useful if you need to distribute time no matter how good or bad it is)
# 按自己需求增加上层NTP服务器
server 0.centos.pool.ntp.org prefer
server 1.centos.pool.ntp.org
server 2.centos.pool.ntp.org
server us.npt.org.cn 

# but it should operate at a high stratum level to let the clients know and force them to
# use any other timesource they may have.
fudge 127.127.1.0 stratum 10

# End of generated ntp.conf --- Please edit this to suite your needs

使用菜单中的Restart Ntp Server 重启服务。

使用Quick NTP Status查看NTP服务的状态,其实就是 watch ntpq -p;如果如下图,基本就成功了

%title插图%num%title插图%num

然后就是你的服务器端设置了。

下面再说下一些术语解释:

# 1. 关于权限设定部分
#   权限的设定主要以 restrict 这个参数来设定,主要的语法为:
#   restrict IP mask netmask_IP parameter
#   其中 IP 可以是软件地址,也可以是 default ,default 就类似 0.0.0.0
#   至于 paramter 则有:
#   ignore :关闭所有的 NTP 联机服务
#   nomodify:表示 Client 端不能更改 Server 端的时间参数,不过,

#   Client 端仍然可以透过 Server 端来进行网络校时。
#   notrust :该 Client 除非通过认证,否则该 Client 来源将被视为不信任网域
#   noquery :不提供 Client 端的时间查询

#   notrap :不提供trap这个远程事件登入

#  如果 paramter 完全没有设定,那就表示该 IP (或网域)“没有任何限制”

restrict default nomodify notrap noquery # 关闭所有的 NTP 要求封包
restrict 127.0.0.1    #这是允许本级查询

#在192.168.0.1/24网段内的服务器就可以通过这台NTP Server进行时间同步了
restrict 192.168.0.1 mask 255.255.255.0 nomodify

# 2. 上层主机的设定
#  要设定上层主机主要以 server 这个参数来设定,语法为:
#  server [IP|HOST Name] [prefer]
#  Server 后面接的就是我们上层 Time Server 啰!而如果 Server 参数
#  后面加上 perfer 的话,那表示我们的 NTP 主机主要以该部主机来作为
#  时间校正的对应。另外,为了解决更新时间封包的传送延迟动作,
#  所以可以使用 driftfile 来规定我们的主机
#  在与 Time Server 沟通时所花费的时间,可以记录在 driftfile
#  后面接的文件内,例如下面的范例中,我们的 NTP server 与
#  cn.pool.ntp.org联机时所花费的时间会记录在 /etc/ntp/drift文件内
server 0.pool.ntp.org

server 1.pool.ntp.org

注:windows原生的做ntp服务不是很稳定,建议重要环境不要使用,不然要死翘翘

1. 修改注册表项

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer

Enabled 设定为 1(默认0)

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Config\

AnnounceFlags 设定为 5 (默认 10)

2. 禁用防火墙或设置例外,UDP 123端口。

3. 运行 services.msc,将Windows Time服务设置成自动(延迟启动)

 

网络设备(如cisco、h3c交换机……)不能正常同步NTP服务器时间:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Config\LocalClockDispersion
值修改为0 (默认为0x0000000a)

ntp服务器是什么,有什么用?

ntp服务器隶属于小众时间频率行业,对于初次接触者和未涉猎此行业的人群来说,就会有很大的疑问:ntp服务器能做什么,为什么会需要ntp服务器?

本文主要通过这两个问题,对ntp服务器进行分总式的说明,希望更多的人能认识ntp服务器,了解ntp服务器,并意识到随着科学技术发展ntp服务器对人文生活,科技发展的重要性和不可或缺性。

ntp服务器是什么,有什么用?

1、什么是ntp服务器?

ntp服务器,对大多数人来说是一个一穷二白的陌生词汇,但是要理解ntp服务器必须先了解什么是ntp和什么是服务器?

1)什么是ntp?

NTP全名“Network TimeProtocol”,即网络时间协议,是由RFC 1305定义的时间同步协议,用来在分布式时间服务器和客户端之间进行时间同步。

NTP基于UDP报文进行传输,使用的UDP端口号为123。使用NTP的目的是对网络内所有具有时钟的设备进行时钟同步,使网络内所有设备的时钟保持一致,从而使设备能够提供基于统一时间的多种应用。对于运行NTP的本地系统,既可以接收来自其他时钟源的同步,又可以作为时钟源同步其他的时钟,并且可以和其他设备互相同步。

2)什么是服务器?

服务器,英文名“server”也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。

服务器的构成包括处理器、硬盘、内存、系统总线等,和通用的计算机架构类似,但是由于需要提供高可靠的服务,因此在处理能力、稳定性、可靠性、安全性、可扩展性、可管理性等方面要求较高。

在网络环境下,根据服务器提供的服务类型不同,分为文件服务器,数据库服务器,应用程序服务器,WEB服务器等。

3)什么是NTP服务器?

前面我们分别了解到了NTP和服务器,那到底是什么NTP服务器呢?根据表面意思理解NTP服务器,即基于NTP协议的服务器,用来在分布式时间服务器和客户端之间进行时间同步。

NTP服务器在应用于时间同步中分为客户端NTP服务器和服务端NTP服务器两种。客户端主要应用于现有NTP网络环境中,获取前端NTP服务器,主要是利用已经存在的网络环境,搭建时间同步系统,实现的是一个从时钟的功能。服务端NTP服务器主要是指用于后端网络环境中设备的时间同步,为网络中的服务器,计算机等网络设备提供一个时间统一的功能,实现主时钟的同步功能。

2、ntp服务器能做什么?

前面,我们很自然的了解到了什么是ntp,也有了一个大概的认识,那么ntp服务器是做什么的,它到底能做什么,这也是我们对于ntp服务器这个名称属性放在这里,我们*需要传达的东西。

NTP服务器主要用来同步网络中各个计算机的时间的协议。它的用途是把计算机的时钟同步到世界协调时UTC,其精度在局域网内可达0.1ms,在互联网上*大多数的地方其精度可以达到1-50ms。它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)进行时间同步,它可以提供高精准度的时间校正,而且可以使用加密确认的方式来防止病毒的协议攻击。

很多人可能会说,我的计算机每天自己走时,为何还需要用一个ntp服务器再同步时间呢?这主要是因为在计算机中芯片本身通常并不具备时钟信号源,因此须由专门的时钟电路提供时钟信号,石英晶体振荡器(Quartz Crystal OSC)就是一种*常用的时钟信号振荡源。石英晶片之所以能当为振荡器使用,是基于它的压电效应:在晶片的两个*上加一电场,会使晶体产生机械变形;在石英晶片上加上交变电压,晶体就会产生机械振动,同时机械变形振动又会产生交变电场。虽然这种交变电场的电压*其微弱,但其振动频率是十分稳定的。

从PC诞生至今,主板上一直都使用一颗14.318MHz的石英晶体振荡器作为基准频率源。主板上除了这颗14.318MHz的晶振,还能找到一颗频率为32.768MHz的晶振,它被用于实时时钟(RTC)电路中,显示精确的时间和日期。初始化后以每秒约18.2次发出脉冲,这些脉冲经过操作系统计算形成BIOS日时钟计数。通过由BIOS电池供电,关机后它仍然正常运行。这也就是为啥我们关了电源,第二天开机依然会显示正确时间的原因。

每个计算机各自有了时钟,但是一旦它们联网后,又出现一个问题:各自运行的计算机时钟,彼此之间日积月累的累计误差如何解决。这就出现了网络时间协议NTP,它是用于互联网中时间同步的标准之一,它的用途是把计算机的时钟同步到世界协调时UTC,并满足于用户环境中的计算机(服务器同理)设备的时间同步。

3、为什么要使用ntp服务器?

对大多数人来说可能会很疑问,我的计算机时间已经够我用了啊,我为何需要单独的ntp服务器。那么问题来了,一个系统里整体运行的所有计算机服务器,如果都独立运行那整个系统工作是否都乱套了?

我们举几个简单的例子:如果公共大楼遇到突发事情每个监控装置时间不一,后期事故调查取证监控时间参差不齐无法还原本质,责任谁来担当?医院系统各个科室职能兼受,若时间相互差开,病人数据记录与实际时间前后出入,若出现分歧责任甩给设备原因,设备是否能够出面来协调?电力电厂系统中有很多需要互相协调合作的设备,若出现各个系统设备之间时间紊乱,就会导致运行机制无法协调合作,那整个电厂的运行失调,所造成的损失无法估量。

所以,ntp服务器在各行各业系统发挥协调作用的同时,已经成为了不可或缺的必备系统,是各个系统稳定运行基于安全因素中必须存在的重要设备。ntp服务器服务器应用于不同行业系统中,为网络内设备提供标准的时间基准,使得各个独立又相互关联的设备有了可参考的维度标准。

随着科技电子产业的发展,ntp服务器在社会国家发展中具有必然存在的重要性。在不同行业,不同领域中由于系统环境的要求对ntp服务器的配置也不尽相同。