我希望在我的应用程序中找到一种方法,将日期和时间与外部源提供的内容同步。
我不想使用手机时间,因为实际上我可能会有5分钟的差异。 5分钟或更少= 10分钟!
我听说过GPS卫星或网络天线中的时间信息。
我已尝试使用System.getCurrentTime,但我得到了设备的当前设备,因此,如果我的设备提前5分钟设置,则会显示错误的时间。
修改
提出一个简短的问题:我怎么能得到这个时间?
答案 0 :(得分:54)
我不知道,但发现这个问题很有意思。所以我挖了android代码...感谢开源:)
您显示的屏幕是DateTimeSettings
。 “使用网络提供的值”复选框与共享偏好String KEY_AUTO_TIME = "auto_time";
以及Settings.System.AUTO_TIME
在2个网络mAutoTimeObserver
中观察到的被叫ServiceStateTracker
观察到此设置:
GsmServiceStateTracker
和CdmaServiceStateTracker
。
当设置变为true时,两个实现都会调用名为revertToNitz()
的方法。
显然NITZ相当于运营商世界中的NTP。
底线:您可以通过revertToNitz()
将时间设置为运营商提供的值。
不幸的是,我还没有找到一种机制来获取网络时间。
如果你真的需要这样做,我担心,你将不得不复制这些ServiceStateTracker
的实现,捕获框架提出的意图(我想),并添加一个getter到mSavedTime
答案 1 :(得分:22)
从http://commons.apache.org/net/download_net.cgi
获取图书馆//NTP server list: http://tf.nist.gov/tf-cgi/servers.cgi
public static final String TIME_SERVER = "time-a.nist.gov";
public static long getCurrentNetworkTime() {
NTPUDPClient timeClient = new NTPUDPClient();
InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
TimeInfo timeInfo = timeClient.getTime(inetAddress);
//long returnTime = timeInfo.getReturnTime(); //local device time
long returnTime = timeInfo.getMessage().getTransmitTimeStamp().getTime(); //server time
Date time = new Date(returnTime);
Log.d(TAG, "Time from " + TIME_SERVER + ": " + time);
return returnTime;
}
getReturnTime()与System.currentTimeMillis()相同。
应该使用getReceiveTimeStamp()或getTransmitTimeStamp()方法。
将系统时间设置为1小时后,您可以看到差异。
local time :
System.currentTimeMillis()
timeInfo.getReturnTime()
timeInfo.getMessage().getOriginateTimeStamp().getTime()
NTP server time :
timeInfo.getMessage().getReceiveTimeStamp().getTime()
timeInfo.getMessage().getTransmitTimeStamp().getTime()
答案 2 :(得分:7)
试试这段代码:
String timeSettings = android.provider.Settings.System.getString(
this.getContentResolver(),
android.provider.Settings.System.AUTO_TIME);
if (timeSettings.contentEquals("0")) {
android.provider.Settings.System.putString(
this.getContentResolver(),
android.provider.Settings.System.AUTO_TIME, "1");
}
Date now = new Date(System.currentTimeMillis());
Log.d("Date", now.toString());
确保在Manifest中添加权限
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
答案 3 :(得分:2)
这似乎对我有用:
LocationManager locMan = (LocationManager) activity.getSystemService(activity.LOCATION_SERVICE);
long networkTS = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER).getTime();
使用Android 2.2 API(第8级)
答案 4 :(得分:1)
NITZ是NTP的一种形式,通过第3层或NAS层发送到移动设备。 通常此消息被视为GMM信息,包含以下信息:
某些运营商不支持这种情况,有些支持并且设置不正确。
第3层信令消息
时间:9:38:49.800
GMM INFORMATION 3GPP TS 24.008 ver 12.12.0 Rel 12(9.4.19)
M Protocol Discriminator(十六进制数据:8)
(0x8) Mobility Management message for GPRS services
M跳过指示符(十六进制数据:0) 值:0 M消息类型(十六进制数据:21) 消息编号:33
O网络时区(十六进制数据:4680) 时区价值:GMT + 2:00 O通用时间和时区(十六进制数据:47716070 70831580) 年份:17 月:06 日:07 小时:07 分钟:38 第二:51 时区价值:GMT + 2:00 O网络夏令时(十六进制数据:490100) 夏令时值:无调整
第3层数据: 08 21 46 80 47 71 60 70 70 83 15 80 49 01 00
答案 5 :(得分:0)
现在您可以获得当前位置的时间,但为此您必须设置系统的持久默认时区。template<class T>
T* laundry_pod(void* ptr){
char buff[sizeof(T)];
std::memcpy(buff, ptr, sizeof(T));
auto* r=::new(ptr)T;
std::memcpy(ptr, buff, sizeof(T));
return r;
}
可以从
setTimeZone(String timeZone)
设置挂钟时间是否应与NTP的自动时间更新同步。
Calendar calendar = Calendar.getInstance();
long now = calendar.getTimeInMillis();
TimeZone current = calendar.getTimeZone();
setAutoTimeEnabled(boolean enabled)
我正在寻找那种类型的答案我读了你的答案,但并不满足,而且有点老了。我找到了新的解决方案并分享。 :)
有关详细信息,请访问:https://developer.android.com/things/reference/com/google/android/things/device/TimeManager.html
答案 6 :(得分:-1)
时间信号未内置于网络天线中:您必须使用NTP协议才能在ntp服务器上检索时间。有很多ntp客户端,可作为独立的可执行文件或库提供。
gps信号确实包含一个精确的时间信号,可用于任何“修复”。
然而,如果没有网络,也没有gps可用,你唯一的选择是借助手机的时间...你最好的解决方案是使用系统范围的设置自动将手机时间同步到gps或ntp时间,然后总是使用手机的时间。
请注意,如果定期同步,手机时间与gps或ntp时间不应有太大差异。另请注意,强制用户同步其时间可能是侵入性的,您最好询问您的用户是否接受同步。最后,你确定你绝对需要一个精确的时间吗?