System.currentTimeMillis()返回华为不正确的时间戳

System.currentTimeMillis()返回华为不正确的时间戳,第1张

概述System.currentTimeMillis()返回华为不正确的时间

问题是System.currentTimeMillis()返回错误的毫秒数,主要是在将来有时达到6个月的不同时间范围,但是从几秒到几个月不等。

这个正在发生的设备是AndroID 5.1.1上的平板型号华为M2-A201W ,内核版本是: **3.10.74-gdbd9055**

我的第一个假设是, NTP不知何故搞砸了,但我有成千上万的这些平板电脑,其中一些没有networking连接,没有SIM卡,所以没有GSM / 3G / 4G。

我使用System.currentTimeMillis()来保存在本地sqlite数据库中创build的行的时间表的列。

如何deBUGgingwindows版本的adb.exe?

在windows 7的VirtualBox中运行的Ubuntu内部不能识别AndroID设备?

androID内核和vanilla linux内核之间的补丁差异

Bluez Architecture:解释这个build筑

androID模拟器/ proc / meminfo不显示正确的值

这种exception情况经常发生(每个System.currentTimeMillis()调用的30%)在我使用的平板电脑上。

如何解决库冲突(apache commons-codec)

CMD:我的AndroID设备使用哪个驱动器号?

从windows中读取androID sms中的消息

AndroID – 不幸的是,相机已经停止 – 默认相机

Meteor Js在windows上支持iOS和AndroID

作为使用System.currentTimeMillis()的解决方法,也许你可以让sqlite处理时间戳创建,看看是否能解决你的问题?

如果你需要几毫秒的timestamp default current_timestamp定义/修改你的“已创建”列的timestamp default current_timestamp或default(strftime('%Y-%m-%d %H:%M:%f','Now'))喜欢这个:

sqlite> create table my_table(ID integer primary key autoincrement not null,name text,created timestamp default(strftime('%Y-%m-%d %H:%M:%f','Now')) not null);

sqlite> insert into my_table(name) values ('MyTestRow1');


sqlite> insert into my_table(name) values ('MyTestRow2');

sqlite> select * from my_table;

1|MyTestRow1|2017-08-07 10:08:50.898


2|MyTestRow2|2017-08-07 10:08:54.701

AndroID平台中的java API调用System.currentTimeMillis()使用POSIX API gettimeofday以毫秒为单位获取时间。 看到这里 。

static jlong System_currentTimeMillis(jnienv*,jclass) { timeval Now; gettimeofday(&Now,NulL); jlong when = Now.tv_sec * 1000LL + Now.tv_usec / 1000; return when; }

它假设每个gettimeofday调用都会成功。 我想你的问题可能发生在这里。

最好检查每个API调用的返回值,并确定发生错误后要执行的 *** 作。

所以我建议一个更可靠的方法在JNI与自己的实现如下。 按顺序调用这些POSIX API,如果gettimeofday失败,调用clock_gettime ,如果再次失败,调用time 。

struct timeval Now; if (gettimeofday(&Now,NulL) != 0) { struct timespec ts; if (clock_gettime(CLOCK_REALTIME,&ts) == 0) { Now.tv_sec = ts.tv_sec; Now.tv_usec = ts.tv_nsec / 1000LL; } else { Now.tv_sec = time(NulL); Now.tv_usec = 0; } } jlong when = Now.tv_sec * 1000LL + Now.tv_usec / 1000LL; __androID_log_print(ANDROID_LOG_INFO,"TAG","%lld",when);

在linux内核中运行“date +%s ”命令本地获取时间戳是什么?

这里, “+%s”是1970-01-01 00:00:00 UTC以来的秒数。 (GNU Coreutils 8.24日期手册)

try { // Run the command Process process = Runtime.getRuntime().exec("date +%s"); BufferedReader bufferedReader = new BufferedReader(new inputStreamReader(process.getinputStream())); // Grab the results StringBuilder log = new StringBuilder(); String line; while ((line = bufferedReader.readline()) != null) { log.append(line); } } catch (IOException e) { e.printstacktrace(); }

如果你打印这个,

Log.e("unix_time: ","" + log.toString());

你会得到一个Unix时间戳,例如1502187111

要将其转换回日期对象,请乘以1000,因为java预期的毫秒数,

Date time = new Date(Long.parseLong(log.toString()) * 1000); Log.e("date_time: ","" + time.toString());

这会给你一个明确的日期格式。 例如8月8日星期二16:15:58 GMT + 06:00 2017

当你没有SIM卡,所以没有GSM / 3G / 4G,你的手机不能根据网络提供的时间/地区更新正确的时间。

因此,具有网络的设备显示正确的时间,而没有网络的其他设备可能显示不正确的时间 – 您必须手动设置正确的时间。 System.currentTimeMilis()从您的系统读取时间。 g但是在电源开启时,时钟正常工作。

检查NTP(UDP端口123)是否被应用程序使用Socket或DatagramSocket阻止。 注意:NTP适用于网络中所有主机或路由器的时钟必须相同的情况。 如果您的设备切换到两个(或更多)不同的网络,并且从不同的来源获取时间更新,则可能会波动。

最终,你的系统时间正在改变,这就是为什么它是波动的。 如果手动禁用自动日期和时间后手动System.currentTimeMilis(),我相信,它不会波动(无异常)。 如果是这种情况,那么你的Huewai平板电脑没有错误。

既然你提到大部分的调用都是正确的,并且只发生了30%的情况,我会为ACTION_TIME_CHANGED和ACTION_TIMEZONE_CHANGED意图广播创建一个接收器,以便在时间变化时找出它。 也许这会给你提供什么改变时间的线索。

与ConnectivityManager一起,您可以检测设备是否已连接,以及您的连接类型,可能是某个连接正在触发时间更改。

// init the register and register the intents,in onStart,using: receiver = new broadcastReceiver() { @OverrIDe public voID onReceive(Context context,Intent intent) { getNetworkInfo(); if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) Log.d(this.getClass().getname(),"Detected a time change. isWifiConn: " + isWifiConn + " isMobileConn: " + isMobileConn); if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) Log.d(this.getClass().getname(),"Detected a timezone change. isWifiConn: " + isWifiConn + " isMobileConn: " + isMobileConn); } }; IntentFilter filters = new IntentFilter(); filters.addAction(Intent.ACTION_TIME_CHANGED); filters.addAction(Intent.ACTION_TIMEZONE_CHANGED); registerReceiver(receiver,filters); Log.d(DEBUG_TAG,"Receiver registered"); // do not forget to unregister the receiver,eg. onStop,using: unregisterReceiver(receiver); //... private voID getNetworkInfo() { ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI); isWifiConn = networkInfo.isConnected(); networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); isMobileConn = networkInfo.isConnected(); Log.d(DEBUG_TAG,"Wifi connected: " + isWifiConn); Log.d(DEBUG_TAG,"Mobile connected: " + isMobileConn); }

这个设备是否有一个真正的硬件RTC? 我无法从Google搜索和阅读规格表中找到明确的答案。 运行:

$ dmesg -s 65535 | grep -i rtc

从一个shell应该给你一个答案。 你应该看到类似这样的内容(随着芯片组和内核版本的变化):

[ 3.816058] rtc_cmos 00:02: RTC can wake from S4 [ 3.816429] rtc_cmos 00:02: rtc core: registered rtc_cmos as rtc0 [ 3.816510] rtc_cmos 00:02: alarms up to one month,y3k,242 bytes nvram,hpet irqs

如果没有grep返回的消息(并且你对整个内核消息缓冲区进行了grep),那么你的答案就是这样。 你没有时间在这些设备上保持时间。 你将永远需要NTP和一个连接到互联网的工作网络来保持这样的设备,而不需要时钟芯片与世界时间同步。

RTC: https : //en.wikipedia.org/wiki/Real-time_clock

总结

以上是内存溢出为你收集整理的System.currentTimeMillis()返回华为不正确的时间戳全部内容,希望文章能够帮你解决System.currentTimeMillis()返回华为不正确的时间戳所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1290430.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-09
下一篇 2022-06-09

发表评论

登录后才能评论

评论列表(0条)

保存