Get actual time from internet ? - android

How to get 'current(actual) time' or 'network operator's time' programmatically if device time is changed ?
I'm trying to get current time through 'getLastKnownLocation' method of 'LocationManager' class. But it gives last location time, but I need current time.
Can anyone tell me a clue about the correct way to get actual time from internet ?
If possible without using any external library.
Thanks in advance.

According to this answer you can get the current time from an NTP server.
support.ntp.org library
Add to your dependency
String timeServer = "server 0.pool.ntp.org";
NTPUDPClient timeClient = new NTPUDPClient();
InetAddress inetAddress = InetAddress.getByName(timeServer);
TimeInfo timeInfo = timeClient.getTime(inetAddress);
long returnTime = timeInfo.getReturnTime();
System.out.println(returnTime)

You can use a rest full api provided by geo names http://www.geonames.org/login it will require lat and long for this purpose for example
http://api.geonames.org/timezoneJSON?lat=51.5034070&lng=-0.1275920&username=your_user_name

For Android:
Add to gradle app module:
compile 'commons-net:commons-net:3.3'
Add to your code:
...
String TAG = "YOUR_APP_TAG";
String TIME_SERVER = "0.europe.pool.ntp.org";
...
public void checkTimeServer() {
try {
NTPUDPClient timeClient = new NTPUDPClient();
InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
TimeInfo timeInfo = timeClient.getTime(inetAddress);
long setverTime = timeInfo.getMessage().getTransmitTimeStamp().getTime();
// store this somewhere and use to correct system time
long timeCorrection = System.currentTimeMillis()-setverTime;
} catch (Exception e) {
Log.v(TAG,"Time server error - "+e.getLocalizedMessage());
}
}
NOTE: timeInfo.getReturnTime() as mentioned in an earlier answer will get you local system time, if you need server time you must use timeInfo.getMessage().getTransmitTimeStamp().getTime().

Getting the time from the third-party servers is not reliable most of the times and some of them are paid services.
If you want to get the exact time and check with the phone whether it is correct or not, irrespective of the proper way, you can use the following simple trick to get the actual time.
private class GetActualTime extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
try {
HttpURLConnection urlConnection = null;
StringBuilder result = new StringBuilder();
try {
URL url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int code = urlConnection.getResponseCode();
if (code == 200) {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = bufferedReader.readLine()) != null)
result.append(line);
in.close();
}
else {
return "error on fetching";
}
return result.toString();
} catch (MalformedURLException e) {
return "malformed URL";
} catch (IOException e) {
return "io exception";
} finally {
if (urlConnection != null) {urlConnection.disconnect();
}
}
} catch (Exception e) { return "null"; }
}
#Override
protected void onPostExecute(String time) {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat mdformat = new SimpleDateFormat("h:mm");
String times = mdformat.format(calendar.getTime());
try {
String areatime = time.substring(time.indexOf(String.valueOf(times)), time.indexOf(String.valueOf(times)) + 5).trim();
Toast.makeText(this, "The actual time is " + areatime, Toast.LENGTH_SHORT).show();
}
catch(IndexOutOfBoundsException e){
Toast.makeText(this, "Mobile time is not same as Internet time", Toast.LENGTH_SHORT).show();
}
}
}
}
Call the class in the onCreate();
new GetActualTime().execute("https://www.google.com/search?q=time");
So this is actually getting the time from Google. This works pretty awesomely in my projects. In order to check whether the system time is wrong, you can use this trick. Instead of depending on the time servers, you can trust Google.
As it is more sensitive in checking, even a minute ahead or lag will catch the exception. You can customise the code if you want to handle that.

Try this :
System.currentTimeMillis();

Related

Getting time from ntp server without allowing the user to manipulate the time

I am trying to get the time from the NTP server. I have a method that it is asking multiple servers for getting the time (if the first one gives a result the other won't be asked they are for backup). In order to resolve the date from the InetAddress I am using TimeInfo from the library: commons-net:commons-net:3.0.1. This resolved the time as it should but it becomes an issue when I will change the time on the phone manually. If I set the time to 1/2/2019 this NTPUDPClient when converting the date it will give this date instead of the actual 1/29/2019. I want to convert this time to the actual date even when the user will change the time on the phone.
Tried searching for how this InetAddress to be resolved with some other component but couldn't find anything.
public Date getCurrentTimeFromNtpServer() {
Date result = null;
NTPUDPClient client = new NTPUDPClient();
client.setDefaultTimeout(2000);
for (String host : NTP_SERVERS) {
try {
InetAddress inetAddress = InetAddress.getByName(host);
TimeInfo timeInfo = client.getTime(inetAddress);
result = DateUtil.toUtc(new Date(timeInfo.getReturnTime()));
break;
} catch (IOException e) {
Logger.warn(TAG, "Failed to get current time MTP", e);
}
}
client.close();
return result;
}
I have finally found the answer. Too many examples on the internet which are not correct. What it should be done is:
public Date getCurrentTimeFromNtpServer() {
Date result = null;
final NTPUDPClient client = new NTPUDPClient();
client.setDefaultTimeout(2000);
for (final String host : NTP_SERVERS) {
try {
final InetAddress inetAddress = InetAddress.getByName(host);
final TimeInfo timeInfo = client.getTime(inetAddress);
final Long time = timeInfo.getMessage().getTransmitTimeStamp().getTime();
result = DateUtil.toUtc(time);
SystemUtil.sleep(500);
break;
} catch (IOException e) {
Logger.warn(TAG, "Failed to get current time NTP", e);
}
}
client.close();
return result;
}
This will give the actual time instead of the one that it is created in the NTPUDPClient and it is the phone time.

Getting current scheduler information for Android app using Android Studio

I'm trying to get the current scheduler information from the path "/sys/block/sda/queue/scheduler" to be output in my application. However, it doesn't seem to return anything, not sure what I am doing wrong here?\
private String getScheduler() {
StringBuffer sb = new StringBuffer();
String file = "/sys/block/sda/queue/scheduler"; // Gets governor for big cores
if (new File(file).exists()) {
try {
BufferedReader br = new BufferedReader(new FileReader(new File(file)));
String aLine;
while ((aLine = br.readLine()) != null)
sb.append(aLine + "\n");
if (br != null)
br.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
if (sb.toString().length() == 0) {
return "File not available";
}
return sb.toString();
}
It always return the string "File not available". I know this should work as I did the same thing for returning the current scaling governor. Do I need to request for root permissions within this app, even though my phone is already rooted?
Any help is greatly appreciated! Thank you so much!

Android: way to detect if the user changed system time while the app was stopped

I'm developing an Android application for in-house of a certain company, and it needs to log the working time of employees. Therefore, the work with system time is crucial. My application badly needs to know when the user changes the system time. Big deal, you say, see this: Is there a way to detect when the user has changed the clock time on their device?
The problem is that the user may circumvent that solution by doing Force Stop of the application prior to changing the time. The application then won't receive system notification, which is brilliantly described here: https://stackoverflow.com/a/19856367/1309803
I don't mind checking that upon the next launch of the application, but how can I possibly know if the user has changed the time? I'm aware about SystemClock.elapsedRealtime(). I could figure time shift based on delta of those values provided that the user hasn't reboot the device, but this is what I'm unsure of. My application is subscribed to BOOT_COMPLETED event, but that one won't be received either while the application is in stopped state.
And, to cap it all, employees of that company are supposed to work in condition of having no network access, so I can't rely on Web servers. So is there any other possible approach?
Getting the time from the third-party servers is not reliable most of the times and some of them are paid services.
If you want to get the exact time and check with the phone whether it is correct or not, irrespective of the proper way, you can use the following simple trick to get the actual time.
private class GetActualTime extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
try {
HttpURLConnection urlConnection = null;
StringBuilder result = new StringBuilder();
try {
URL url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int code = urlConnection.getResponseCode();
if (code == 200) {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = bufferedReader.readLine()) != null)
result.append(line);
in.close();
}
else {
return "error on fetching";
}
return result.toString();
} catch (MalformedURLException e) {
return "malformed URL";
} catch (IOException e) {
return "io exception";
} finally {
if (urlConnection != null) {urlConnection.disconnect();
}
}
} catch (Exception e) { return "null"; }
}
#Override
protected void onPostExecute(String time) {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat mdformat = new SimpleDateFormat("h:mm");
String times = mdformat.format(calendar.getTime());
try {
String areatime = time.substring(time.indexOf(String.valueOf(times)), time.indexOf(String.valueOf(times)) + 5).trim();
Toast.makeText(this, "The actual time is " + areatime, Toast.LENGTH_SHORT).show();
}
catch(IndexOutOfBoundsException e){
Toast.makeText(this, "Mobile time is not same as Internet time", Toast.LENGTH_SHORT).show();
}
}
}
}
Call the class in the onCreate();
new GetActualTime().execute("https://www.google.com/search?q=time");
So this is actually getting the time from Google. This works pretty awesomely in my projects. In order to check whether the system time is wrong, you can use this trick. Instead of depending on the time servers, you can trust Google.
As it is more sensitive in checking, even a minute ahead or lag will catch the exception. You can customise the code if you want to handle that.

Read all lines from BufferedReader before continuing

I am having a bit of an issue with my app. I receive a data through a socket, via a BufferedReader. I loop round with while ((sLine = reader.readLine ()) != null) and append the sLine to a StringBuilder object. I also spend a new line \n to the builder.
The plan is that once the builder is all finished, String sTotal = builder.toString()is called and a total is passed to the next routine.
However, the next routine is instead being called once for each line rather than with the string as a whole. The routine call is outside the loop above so I really don't know why!
Hope someone can help...
Edit: Code extract below.
public void run() {
try {
oServerSocket = new ServerSocket(iPort);
while ((!Thread.currentThread().isInterrupted()) && (!bStopThread)) {
try {
oSocket = oServerSocket.accept();
this.brInput = new BufferedReader(new InputStreamReader(this.oSocket.getInputStream()));
StringBuilder sbReadTotal = new StringBuilder();
String sReadXML = "";
while ((sReadXML = brInput.readLine()) != null) {
sbReadTotal.append("\n");
sbReadTotal.append(sReadXML);
}
sReadXML = sbReadTotal.toString();
Log.d("XMLDATA", sReadXML);
processXML(sReadXML);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
/* Nothing Yet */
e.printStackTrace();
}
}
If you're exiting your internal while loop, it means you reached the end of your input stream (that's when readLine() returns null according to the docs).
You should be looking into the client, and not the server. What's establishing the client socket? Are you sure it's not establishing a separate connection for each line it sends?

How to get connected device count in hotspot(AP) programmatically [Android]

Am working on a application which need to show the hotspot details including the number of device connected to the hotspot
I tried this but not worked ,
private int countNumMac()
{
int macCount =0;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("/proc/net/arp"));
String line;
System.out.println(br.toString());
while ((line = br.readLine()) != null) {
String[] splitted = line.split(" +");
System.out.println("splitted :"+splitted);
if (splitted != null && splitted.length >= 4) {
// Basic sanity check
String mac = splitted[3];
if (mac.matches("..:..:..:..:..:..")) {
macCount++;
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(macCount == 0)
return 0;
else
return macCount-1;
}
Is there any other method to count the number of device connected to hotspot..
The code you entered needs root access
Take a look at this library. I hope it solves your problem
https://github.com/nickrussler/Android-Wifi-Hotspot-Manager-Class
You do not need root access to accomplish what you are trying to do.
As far as counting connected devices you can easily just ping each possible host on the subnet and then count them.
Here is an open-source project that may give you some stepping stones along your journey to your new app :)
https://github.com/VREMSoftwareDevelopment/WiFiAnalyzer

Categories

Resources