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

前言

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

NTP服务器

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

解决方案

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

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

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

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

代码及目录

GitHub: https://blog.csdn.net/DeMonliuhui/article/details/82226601

这里写图片描述

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

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

效果

这里写图片描述

参考

http://www.programgo.com/article/54422482620/

相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页