本文地址:http://www.jianshu.com/p/47d4944196d2 [FBI WARMING]
背景
项目的打卡模块要求服务器挂了,网络不好但能定位的时候也能打卡,打卡时间客户端确定,先缓存本地,有网络后上传服务器,就是打卡时间是要客户端确定的,不是服务器确定的。那么问题就来了,有个小伙伴把手机调后半个小时关闭网络后提前下班了
一种防止Android 篡改手机时间的方法
大概是想就是在某个一个时刻获取服务器时间,记录此时 服务器时间和距离开机的时间,someServerTime和someBootedTime。那么在某个时刻T 的真实时间就是先算出T 时刻和someBootedTime 的时间差SystemClock.elapsedRealtime()-someBootedTime;也就是:
long period = SystemClock.elapsedRealtime() -someBootedTime;
long nowTime= someServerTime + period;
关于SystemClock.elapsedRealtime()
它是系统启动到当前时刻经过的时间,包括了系统睡眠经过的时间。现在大部分的手机都有重启和关机,那么重启和关机后获取的SystemClock.elapsedRealtime() 有什么不同呢?当然有的
简单来说,手机开关机和电脑类似,是对硬件的状态进行检测,关机时系统和硬件全部关闭。再开机则再次检测所有硬件情况,然后重新加载所有数据。
而重启是手机软件层面的重新启动,并不涉及硬件,它会使系统自动跳过开关机时需要执行的很多步骤,直接进入操作系统。
Android 手机一般都有关机和重启的选项,iphone 其实也有,重启 长安电源和Home 按键大于10秒就是强制重启(这个重启和Android 的重启是不是一个东西就不知道了)
所以SystemClock.elapsedRealtime() 在两种情况的区别就不言而喻了!
不知道有没有遇到SystemClock.elapsedRealtime() 跑久了不准确的情况?
还会遇到的问题
因为这种方法是关机后再打开App需要一次联网校准的过程,所以还是有一个缺陷:关闭时间网络校准后修改时间关机重启手机重启App这个时候时间肯定没法校准了,时间也只能由着用户修改了!但是也别急,最起码我们能知道用户干了这件事,能够标记,次数多了,可以进行综合的稽查。
可以使用的NTP服务器&多NTP 服务器保证服务可用性
Demo on GitHub: https://github.com/AnyLifeZLB/MVP-Dagger2-Rxjava2
搜索class NtpUtils.
我们项目中一直使用的是以下几个NTP服务器 。你也可以使用其他的
"time.apple.com",
"ntp3.aliyun.com",
"cn.pool.ntp.org"
Observable.create((ObservableOnSubscribe<Long>) emitter -> {
for (int i = 0; i < ntpServerHost.length; i++) {
long time = getTimeFromNtpServer(ntpServerHost[i]);
if (time != -1) {
emitter.onNext(time);
break;
}
if ((i == ntpServerHost.length - 1) && (time == -1)) {
emitter.onError(null);
}
}
})
.compose(SwitchSchedulers.applySchedulers())
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Long o) {
spDao.saveData(SPKey.KEY_SOME_BOOTED_TIME, SystemClock.elapsedRealtime());
spDao.saveData(SPKey.KEY_SOME_SERVER_TIME, o.longValue());
}
@Override
public void onError(Throwable e) {
Log.e("TIME", e.toString() + "---");
}
@Override
public void onComplete() {
}
});
More ,没有GPS不开Wi-Fi也可能被高精度定位
多说一句看下面的图我相信大家会相信没有GPS,不开Wi-Fi也可能被高精度定位的,我们的打卡就算没开GPS权限,不连接Wi-Fi也能高精度定位,上传了电话基站的ID。所以某些情况下Android 手机的位置隐私是不容易隐藏的,手机基站ID 都能拿到,iOS好像拿不到
