Reputation: 39558
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!
I have heard about time information in the GPS satellites or in Network antennas.
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.
EDIT
To make a short question: how can I get this time?
Upvotes: 63
Views: 125440
Reputation: 2833
For others who need a reliable time in Android, you can use this helpful library: https://github.com/homayoonahmadi/RealTime
Initialize it in Application
class using time servers, NTP servers, or device location provider (GPS):
RealTime.builder(this)
.withGpsProvider()
.withNtpServer("time.google.com")
.withNtpServer("time.windows.com")
.withTimeServer("https://google.com")
.withTimeServer(BuildConfig.API_BASE_URL)
.setLoggingEnabled(BuildConfig.DEBUG)
.setSyncBackoffDelay(5, TimeUnit.MINUTES)
.build { date -> logd("RealTime initialized: $date") }
It needs to get current reliable time once until next device reboot. And you can get time like this:
if (RealTime.isInitialized()) {
val reliableTime = RealTime.now()
}
Upvotes: 0
Reputation: 6835
I read that this
LocationManager locMan = (LocationManager) activity.getSystemService(activity.LOCATION_SERVICE);
long time = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER).getTime();
provides correct time, without internet at the cost of some blocking processing.
Upvotes: 0
Reputation: 1297
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
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.
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
Upvotes: 0
Reputation: 21
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:
Certain carriers dont support this and some support it and have it setup incorrectly.
LAYER 3 SIGNALING MESSAGE
Time: 9:38:49.800
GMM INFORMATION 3GPP TS 24.008 ver 12.12.0 Rel 12 (9.4.19)
M Protocol Discriminator (hex data: 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
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
Layer 3 data: 08 21 46 80 47 71 60 70 70 83 15 80 49 01 00
Upvotes: 2
Reputation: 143
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
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
Upvotes: 7
Reputation: 2239
Get the library from 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().
getReceiveTimeStamp() or getTransmitTimeStamp() method should be used.
You can see the difference after setting system time to 1 hour ago.
local time :
System.currentTimeMillis()
timeInfo.getReturnTime()
timeInfo.getMessage().getOriginateTimeStamp().getTime()
NTP server time :
timeInfo.getMessage().getReceiveTimeStamp().getTime()
timeInfo.getMessage().getTransmitTimeStamp().getTime()
Upvotes: 26
Reputation: 107
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)
Upvotes: 1
Reputation: 26994
I didn't know, but found the question interesting. So I dug in the android code... Thanks open-source :)
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
This settings is observed by an observed called mAutoTimeObserver
in the 2 network ServiceStateTracker
s:
GsmServiceStateTracker
and CdmaServiceStateTracker
.
Both implementations call a method called revertToNitz()
when the settings becomes true.
Apparently NITZ is the equivalent of NTP in the carrier world.
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 ServiceStateTracker
s implementations, catch the intent raised by the framework (I suppose), and add a getter to mSavedTime
.
Upvotes: 64
Reputation: 23303
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.
the gps signal does indeed include a precise time signal, which is available with any "fix".
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.
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 ?
Upvotes: -1