我怎样才能获得“网络”时间(从“使用网络提供价值”的“自动”设置),而不是手机上的时间?

时间:2021-04-15 16:02:38

I would like in my application to find a way to synch the date and time with something given by an external source.

我希望在我的应用程序中找到一种方法来同步日期和时间与外部源给出的内容。

I don't want to use the phone time because I might get a difference of maybe 5 minutes around real time. and 5 minutes extra or less = 10 minutes!

我不想用电话时间,因为我可能会有5分钟的间隔。额外或少于5分钟= 10分钟!

I have heard about time information in the GPS satellites or in Network antennas.

我听说过GPS卫星或网络天线的时间信息。

I have tried with System.getCurrentTime but i get the current the of the device, so, if my device is set up 5 minutes earlier, it display the wrong time.

我试过系统。getCurrentTime但是我得到了设备的当前值,因此,如果我的设备提前5分钟设置,它会显示错误的时间。

EDIT

编辑

To make a short question: how can I get this time?

我想问一个简短的问题:这次我能得到什么?

我怎样才能获得“网络”时间(从“使用网络提供价值”的“自动”设置),而不是手机上的时间?

7 个解决方案

#1


52  

I didn't know, but found the question interesting. So I dug in the android code... Thanks open-source :)

我不知道,但觉得这个问题很有趣。所以我挖掘了android代码……由于开源:)

The screen you show is DateTimeSettings. The checkbox "Use network-provided values" is associated to the shared preference String KEY_AUTO_TIME = "auto_time"; and also to Settings.System.AUTO_TIME

您显示的屏幕是日期时间间隔。“使用网络提供的值”复选框与共享首选项字符串KEY_AUTO_TIME =“auto_time”相关联;同时Settings.System.AUTO_TIME

This settings is observed by an observed called mAutoTimeObserver in the 2 network ServiceStateTrackers: GsmServiceStateTracker and CdmaServiceStateTracker.

在GsmServiceStateTracker和CdmaServiceStateTracker两个网络服务跟踪器中,一个名为mAutoTimeObserver的观察者观察到了这些设置。

Both implementations call a method called revertToNitz() when the settings becomes true. Apparently NITZ is the equivalent of NTP in the carrier world.

两种实现都调用一个名为revertToNitz()的方法,当设置变为真时。显然,NITZ在航母世界里相当于NTP。

Bottom line: You can set the time to the value provided by the carrier thanks to revertToNitz(). Unfortunately, I haven't found a mechanism to get the network time. If you really need to do this, I'm afraid, you'll have to copy these ServiceStateTrackers implementations, catch the intent raised by the framework (I suppose), and add a getter to mSavedTime.

底线:您可以通过revertToNitz()将时间设置为承运人提供的值。不幸的是,我还没有找到一个获得网络时间的机制。如果您确实需要这样做,恐怕您必须复制这些ServiceStateTrackers实现,捕获框架(我想)提出的意图,并向mSavedTime添加一个getter。

#2


21  

Get the library from http://commons.apache.org/net/download_net.cgi

从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() is same as System.currentTimeMillis().

getReturnTime()与System.currentTimeMillis()相同。

getReceiveTimeStamp() or getTransmitTimeStamp() method should be used.

应该使用getReceiveTimeStamp()或gettimestamp()方法。

You can see the difference after setting system time to 1 hour ago.

将系统时间设置为1小时后,您可以看到差异。

local time :
System.currentTimeMillis()
timeInfo.getReturnTime()
timeInfo.getMessage().getOriginateTimeStamp().getTime()

NTP server time :
timeInfo.getMessage().getReceiveTimeStamp().getTime()
timeInfo.getMessage().getTransmitTimeStamp().getTime()

#3


6  

Try this snippet of code:

尝试以下代码片段:

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

Make sure to add permission in Manifest

确保在Manifest中添加权限

<uses-permission android:name="android.permission.WRITE_SETTINGS"/>

#4


3  

This seemed to work for me:

这似乎对我有用:

LocationManager locMan = (LocationManager) activity.getSystemService(activity.LOCATION_SERVICE);
long networkTS = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER).getTime();

Working on Android 2.2 API (Level 8)

开发Android 2.2 API(第8级)

#5


1  

NITZ is a form of NTP and is sent to the mobile device over Layer 3 or NAS layers. Commonly this message is seen as GMM Info and contains the following informaiton:

NITZ是NTP的一种形式,通过第3层或NAS层发送到移动设备。此消息通常被视为GMM信息,包含以下信息:

Certain carriers dont support this and some support it and have it setup incorrectly.

有些运营商不支持这一点,有些则支持这一点,而且设置不正确。

LAYER 3 SIGNALING MESSAGE

层3信令消息

Time: 9:38:49.800

时间:9:38:49.800

GMM INFORMATION 3GPP TS 24.008 ver 12.12.0 Rel 12 (9.4.19)

GMM信息3GPP TS 24.008 ver 12.12.0 Rel 12 (9.4.19)

M Protocol Discriminator (hex data: 8)

M协议鉴别器(十六进制数据:8)

(0x8) Mobility Management message for GPRS services

M Skip Indicator (hex data: 0) Value: 0 M Message Type (hex data: 21) Message number: 33

M跳转指示器(十六进制数据:0)值:0 M消息类型(十六进制数据:21)消息号:33

O Network time zone (hex data: 4680) Time Zone value: GMT+2:00 O Universal time and time zone (hex data: 47716070 70831580) Year: 17 Month: 06 Day: 07 Hour: 07 Minute :38 Second: 51 Time zone value: GMT+2:00 O Network Daylight Saving Time (hex data: 490100) Daylight Saving Time value: No adjustment

O网络时区(十六进制数据:4680)时区值:两点O世界时和时区(十六进制数据:47716070 70831580):17月:06日:7小时:07分钟:38秒:51时区值:GMT +两点O网络夏令时(十六进制数据:490100)夏令时价值:没有调整

Layer 3 data: 08 21 46 80 47 71 60 70 70 83 15 80 49 01 00

第3层数据:08 21 46 80 47 70 70 83 15 80 49 01 00

#6


0  

Now you can get time for the current location but for this you have to set the system's persistent default time zone.setTimeZone(String timeZone) which can be get from

现在您可以获得当前位置的时间,但为此您必须设置系统的持久默认时区。可以从其中获取的setTimeZone(字符串时区)

Calendar calendar = Calendar.getInstance();
 long now = calendar.getTimeInMillis();
 TimeZone current = calendar.getTimeZone();

setAutoTimeEnabled(boolean enabled)

Sets whether or not wall clock time should sync with automatic time updates from NTP.

设置壁挂式时钟时间是否应该与NTP的自动时间更新同步。

TimeManager timeManager = TimeManager.getInstance();
 // Use 24-hour time
 timeManager.setTimeFormat(TimeManager.FORMAT_24);

 // Set clock time to noon
 Calendar calendar = Calendar.getInstance();
 calendar.set(Calendar.MILLISECOND, 0);
 calendar.set(Calendar.SECOND, 0);
 calendar.set(Calendar.MINUTE, 0);
 calendar.set(Calendar.HOUR_OF_DAY, 12);
 long timeStamp = calendar.getTimeInMillis();
 timeManager.setTime(timeStamp);

I was looking for that type of answer I read your answer but didn't satisfied and it was bit old. I found the new solution and share it. :)

我在找那种类型的答案我读了你的答案但不满意,它有点旧了。我找到了新的解决方案并分享了它。:)

For more information visit: https://developer.android.com/things/reference/com/google/android/things/device/TimeManager.html

更多信息请访问:https://developer.android.com/things/reference/com/google/android/things/device/TimeManager.html

#7


-2  

the time signal is not built into network antennas: you have to use the NTP protocol in order to retrieve the time on a ntp server. there are plenty of ntp clients, available as standalone executables or libraries.

时间信号没有内置到网络天线中:您必须使用NTP协议来检索NTP服务器上的时间。有大量的ntp客户端,可以作为独立的可执行文件或库使用。

the gps signal does indeed include a precise time signal, which is available with any "fix".

gps信号确实包含一个精确的时间信号,任何“修正”都可以使用。

however, if nor the network, nor the gps are available, your only choice is to resort on the time of the phone... your best solution would be to use a system wide setting to synchronize automatically the phone time to the gps or ntp time, then always use the time of the phone.

然而,如果既没有网络,也没有gps,你唯一的选择就是在打电话的时候……最好的解决方案是使用一个系统范围内的设置来自动同步手机时间到gps或ntp时间,然后总是使用手机的时间。

note that the phone time, if synchronized regularly, should not differ much from the gps or ntp time. also note that forcing a user to synchronize its time may be intrusive, you 'd better ask your user if he accepts synchronizing. at last, are you sure you absolutely need a time that precise ?

注意,如果定期同步,电话时间应该与gps或ntp时间相差不大。还要注意,强制用户同步时间可能会造成干扰,您最好问问您的用户是否接受同步。最后,你确定你绝对需要这么精确的时间吗?

#1


52  

I didn't know, but found the question interesting. So I dug in the android code... Thanks open-source :)

我不知道,但觉得这个问题很有趣。所以我挖掘了android代码……由于开源:)

The screen you show is DateTimeSettings. The checkbox "Use network-provided values" is associated to the shared preference String KEY_AUTO_TIME = "auto_time"; and also to Settings.System.AUTO_TIME

您显示的屏幕是日期时间间隔。“使用网络提供的值”复选框与共享首选项字符串KEY_AUTO_TIME =“auto_time”相关联;同时Settings.System.AUTO_TIME

This settings is observed by an observed called mAutoTimeObserver in the 2 network ServiceStateTrackers: GsmServiceStateTracker and CdmaServiceStateTracker.

在GsmServiceStateTracker和CdmaServiceStateTracker两个网络服务跟踪器中,一个名为mAutoTimeObserver的观察者观察到了这些设置。

Both implementations call a method called revertToNitz() when the settings becomes true. Apparently NITZ is the equivalent of NTP in the carrier world.

两种实现都调用一个名为revertToNitz()的方法,当设置变为真时。显然,NITZ在航母世界里相当于NTP。

Bottom line: You can set the time to the value provided by the carrier thanks to revertToNitz(). Unfortunately, I haven't found a mechanism to get the network time. If you really need to do this, I'm afraid, you'll have to copy these ServiceStateTrackers implementations, catch the intent raised by the framework (I suppose), and add a getter to mSavedTime.

底线:您可以通过revertToNitz()将时间设置为承运人提供的值。不幸的是,我还没有找到一个获得网络时间的机制。如果您确实需要这样做,恐怕您必须复制这些ServiceStateTrackers实现,捕获框架(我想)提出的意图,并向mSavedTime添加一个getter。

#2


21  

Get the library from http://commons.apache.org/net/download_net.cgi

从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() is same as System.currentTimeMillis().

getReturnTime()与System.currentTimeMillis()相同。

getReceiveTimeStamp() or getTransmitTimeStamp() method should be used.

应该使用getReceiveTimeStamp()或gettimestamp()方法。

You can see the difference after setting system time to 1 hour ago.

将系统时间设置为1小时后,您可以看到差异。

local time :
System.currentTimeMillis()
timeInfo.getReturnTime()
timeInfo.getMessage().getOriginateTimeStamp().getTime()

NTP server time :
timeInfo.getMessage().getReceiveTimeStamp().getTime()
timeInfo.getMessage().getTransmitTimeStamp().getTime()

#3


6  

Try this snippet of code:

尝试以下代码片段:

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

Make sure to add permission in Manifest

确保在Manifest中添加权限

<uses-permission android:name="android.permission.WRITE_SETTINGS"/>

#4


3  

This seemed to work for me:

这似乎对我有用:

LocationManager locMan = (LocationManager) activity.getSystemService(activity.LOCATION_SERVICE);
long networkTS = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER).getTime();

Working on Android 2.2 API (Level 8)

开发Android 2.2 API(第8级)

#5


1  

NITZ is a form of NTP and is sent to the mobile device over Layer 3 or NAS layers. Commonly this message is seen as GMM Info and contains the following informaiton:

NITZ是NTP的一种形式,通过第3层或NAS层发送到移动设备。此消息通常被视为GMM信息,包含以下信息:

Certain carriers dont support this and some support it and have it setup incorrectly.

有些运营商不支持这一点,有些则支持这一点,而且设置不正确。

LAYER 3 SIGNALING MESSAGE

层3信令消息

Time: 9:38:49.800

时间:9:38:49.800

GMM INFORMATION 3GPP TS 24.008 ver 12.12.0 Rel 12 (9.4.19)

GMM信息3GPP TS 24.008 ver 12.12.0 Rel 12 (9.4.19)

M Protocol Discriminator (hex data: 8)

M协议鉴别器(十六进制数据:8)

(0x8) Mobility Management message for GPRS services

M Skip Indicator (hex data: 0) Value: 0 M Message Type (hex data: 21) Message number: 33

M跳转指示器(十六进制数据:0)值:0 M消息类型(十六进制数据:21)消息号:33

O Network time zone (hex data: 4680) Time Zone value: GMT+2:00 O Universal time and time zone (hex data: 47716070 70831580) Year: 17 Month: 06 Day: 07 Hour: 07 Minute :38 Second: 51 Time zone value: GMT+2:00 O Network Daylight Saving Time (hex data: 490100) Daylight Saving Time value: No adjustment

O网络时区(十六进制数据:4680)时区值:两点O世界时和时区(十六进制数据:47716070 70831580):17月:06日:7小时:07分钟:38秒:51时区值:GMT +两点O网络夏令时(十六进制数据:490100)夏令时价值:没有调整

Layer 3 data: 08 21 46 80 47 71 60 70 70 83 15 80 49 01 00

第3层数据:08 21 46 80 47 70 70 83 15 80 49 01 00

#6


0  

Now you can get time for the current location but for this you have to set the system's persistent default time zone.setTimeZone(String timeZone) which can be get from

现在您可以获得当前位置的时间,但为此您必须设置系统的持久默认时区。可以从其中获取的setTimeZone(字符串时区)

Calendar calendar = Calendar.getInstance();
 long now = calendar.getTimeInMillis();
 TimeZone current = calendar.getTimeZone();

setAutoTimeEnabled(boolean enabled)

Sets whether or not wall clock time should sync with automatic time updates from NTP.

设置壁挂式时钟时间是否应该与NTP的自动时间更新同步。

TimeManager timeManager = TimeManager.getInstance();
 // Use 24-hour time
 timeManager.setTimeFormat(TimeManager.FORMAT_24);

 // Set clock time to noon
 Calendar calendar = Calendar.getInstance();
 calendar.set(Calendar.MILLISECOND, 0);
 calendar.set(Calendar.SECOND, 0);
 calendar.set(Calendar.MINUTE, 0);
 calendar.set(Calendar.HOUR_OF_DAY, 12);
 long timeStamp = calendar.getTimeInMillis();
 timeManager.setTime(timeStamp);

I was looking for that type of answer I read your answer but didn't satisfied and it was bit old. I found the new solution and share it. :)

我在找那种类型的答案我读了你的答案但不满意,它有点旧了。我找到了新的解决方案并分享了它。:)

For more information visit: https://developer.android.com/things/reference/com/google/android/things/device/TimeManager.html

更多信息请访问:https://developer.android.com/things/reference/com/google/android/things/device/TimeManager.html

#7


-2  

the time signal is not built into network antennas: you have to use the NTP protocol in order to retrieve the time on a ntp server. there are plenty of ntp clients, available as standalone executables or libraries.

时间信号没有内置到网络天线中:您必须使用NTP协议来检索NTP服务器上的时间。有大量的ntp客户端,可以作为独立的可执行文件或库使用。

the gps signal does indeed include a precise time signal, which is available with any "fix".

gps信号确实包含一个精确的时间信号,任何“修正”都可以使用。

however, if nor the network, nor the gps are available, your only choice is to resort on the time of the phone... your best solution would be to use a system wide setting to synchronize automatically the phone time to the gps or ntp time, then always use the time of the phone.

然而,如果既没有网络,也没有gps,你唯一的选择就是在打电话的时候……最好的解决方案是使用一个系统范围内的设置来自动同步手机时间到gps或ntp时间,然后总是使用手机的时间。

note that the phone time, if synchronized regularly, should not differ much from the gps or ntp time. also note that forcing a user to synchronize its time may be intrusive, you 'd better ask your user if he accepts synchronizing. at last, are you sure you absolutely need a time that precise ?

注意,如果定期同步,电话时间应该与gps或ntp时间相差不大。还要注意,强制用户同步时间可能会造成干扰,您最好问问您的用户是否接受同步。最后,你确定你绝对需要这么精确的时间吗?