I'm doing a camera application that will automatically geo-tag each picture taken. Using
LocationManager.requestLocationUpdates() //simply to get the GPS running
LocationManager.getLastKnownLocation() //for each picture, to get coordinates
is mostly enough to simply pluck out coordinates from the phone as fast as possible, since it is still a camera application and you don't want to waste time getting GPS data.
(Assume using GPS_PROVIDER only, not NETWORK_PROVIDER pls)
However the issue will be if the user enters a tunnel for example and the phone is unable to continue getting updates. 10 minutes later when getLastKnownLocation() is called, I will get an outdated location.
I want to find a way in which I can set an 'expiry' time on the Location, depending on individual comfort level.
In other words, keep using getLastKnownLocation(), but if the data is (for example) more than 5 minutes old, don't bother with it, and I rather have a 'null' location. if the data is 2 minutes old however, that still is fine
You can implement this yourself. There's nothing in the underlying API that includes this, but it's perfectly fine to stash the time that you initiated the request (or got the last one) in your app, perhaps in a SharedPreferences. You also have to be weary of things like how fast the user is moving, etc.., so in general you might need to put a fair amount of thought effort into determining how you want to do this. There's not any way (in the API) to find out how fresh the call to .getLastLocation() will get you. For a few minutes it's probably best to employ the technique I mentioned. For a lot longer you might want to consider something like an AlarmManager (which you should be using anyway if your app runs on a timescale that is that long). You seem to be using .getLastLocation more than I do, however. I often simply just request updates and then "put the dot down" whenever I get the first update. In general I've found that .getLastKnownLocation() isn't really all that reliable, but maybe that's just because I don't use apps with my location very often.
Managed to find out that each Location returned had a time variable
long time_a = my_loc.getTime();
We can use this to compare with
Calendar cal = Calendar.getInstance();
long time_b = cal.getTimeInMillis();
long interval = time_a - time_b;
The interval is then the 'validity' of the location fix, and can be easily used for my purpose :)
Related
I'm seeing in docs that the object Location has a method getTime().
In my app, I need the server time, but sometimes, app can be offline, so I have no choice to get cel time. I would gladly use Location.getTime, but it is not clear to me where this time is coming from?
The Cel or the GPS Satelite???
Is it a reliable data for getting the current hour when app is offline?
As discussed in this question, Location.getTime() returns either
the device time (System.currentTimeMillis()) if Location.getProvider().equals(LocationManager.NETWORK_PROVIDER)
or
the GPS (satellite) time (in milliseconds but with 1s precision) if Location.getProvider().equals(LocationManager.GPS_PROVIDER)
Since the GPS location determination is based on the knowledge of the precise time, I would say it is at least as reliable as the time you would get from a server.
You can apply your local time zone to the GPS timestamp to get a human readable time, which sould be equal to a properly synced device time (in my case most of the devices where not, so it was even better to use the GPS time).
It is useful when you don't need a very precise time and you just want to know the date only regardless to precise time. Since as the documentation says:
All locations generated by the LocationManager are guaranteed to have
a valid UTC time, however remember that the system time may have
changed since the location was generated.
Also take a look at getElapsedRealtimeNanos() it seems to be more precise.
I've noticed that System.currentTimeMillis() time is device dependent. If I change the time on the device's clock, this method will return a different answer.
For example: If the real time now is 10:00, and I change the clock on my device to 9:30, then System.currentTimeMillis() will return the 9:30 time (in milliseconds..).
I've also tried this answer and some other answers, but didn't find anything useful.
I should state that my app works mostly offline.
Is there a way to get the real current time (device independent) without external API?
If it were not for the 'offline' part, I'd have suggested to use a time server, but given that your app is offline most of the time that might not be a good solution.
If you don't need the actual time but just a time that cannot be messed with, you can use SystemClock.elapsedRealtime() which gives you the time since the device last booted.
You could also combine time server and SystemClock.elapsedRealtime(): Fetch the time from timer server once (e.g. after bootup) and from then on add elapsedRealtime() to that initial value (minus the elapsedRealtime value of when you get the timerserver value).
If you use the GPS location provider, getTime() will return the UTC time derived from the GPS signal, rather than the device time. The GPS location provider can work offline - but it will be much slower to obtain a fix compared to being online when it can access the A-GPS info.
I'm developing an application, which will have a custom yearly subscription license. I need to know exactly how much time has passed. The user could keep the device offline, therefore I can't check the time through internet. The user could turn back the clock, therefore I can't be sure of really passed time. Is there a way to get the real time elapsed?
I think you can use System. nanoTime(), which can help you measure an absolute elapsed time (as opposed to System.currentMillis() which will be adjusted if the system clock is changed).
See the nanoTime and currentMillis javadocs for more information.
ps: I have not tested it.
you can have a preference or database that need to be stored the time when user install the application ... and you will always compare the time passed with the difference between stored time - current system time ........
or may be make a service to get network time
This question may be slightly long-winded, but is open for many suggestions.
Problem Statement:
We have several API level 8 (Android 2.2) MyTouch devices that we will be using for recording acceleration data at an amusement park, namely on a roller coaster. We also have a visualization feature that allows us to plot and view the accelerometer points as a function of time that they were recorded at. Here is where we have a dilemma! The system times on the Android devices aren't all the same, nor can they be set to the same time with millisecond precision (only manually with minute precision, which is awful).
Solution Attempts:
So, I first resorted to recording data according to a GPS time found at the start of the app. Long process short: get GPS time, get System time, get difference, and upon recording a data point, get system time again and add the difference back onto the time, label that as starting time of recording, and increment by 200 milliseconds for each recorded data point from there. However, there are 2 problems (for getting GPS time):
Using getLastKnownLocation() isn't too accurate. Actually, it seems very inaccurate. It is giving me times that are 9 minutes off the current GMT/UTC time. Coincidentally, however, system time is also nearly 9 minutes off on the Android device... the difference between GPS time and System time is usually between 1000 and 5000 milliseconds (1 to 5 seconds). I suppose there is a chance my code is wrong. I pasted it below for you to see.
requestSingleUpdate() would be great to use, as it would get a more recent location and perhaps a very accurate time. Problem? Requires API level 9... devices we don't have.
Ideas:
Here's an idea I had though - what if I somehow pulled a global time from a website and used the time pulled from there as the time of recording? Problem here - I have no idea how to do that, it is just wishful thinking of mine...
Another idea - is there some sort of global getTime()-type of function that I simply don't know about?
Reasoning why I want Android's to pull time from a similar clock:
Imagine two people sitting on a roller coaster - one in the front seat, one on the back. When recording data, the person in front will obviously experience accelerations slightly before the person in the back will (and we want to see this on our visualization graph). That is why is it crucial, to millisecond precision, that these points are recorded according to a single, global time.
Code:
Criteria c = new Criteria();
c.setAccuracy(Criteria.ACCURACY_FINE);
if (mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
mLocationManager.requestLocationUpdates(mLocationManager.getBestProvider(c, true), 0, 0, AmusementPark.this);
Criteria criteria = new Criteria();
String bestProvider = mLocationManager.getBestProvider(criteria, false);
Location location = mLocationManager.getLastKnownLocation(bestProvider);
try {
gpsTime = location.getTime();
systemTime = System.currentTimeMillis();
timeDif = gpsTime - systemTime;
Log.e("timedif", "GPS: " + gpsTime + ", System: " + systemTime +", Dif: " + timeDif);
} catch (NullPointerException e){
}
}
Update:
Here, someone suggests a sort of "server" getTime(). I really like his code/answer, but what is this "server" and/or how do I set one up, if this is the best solution?
I think the "server" the responder is referring to in that post is to set up a dedicated time server. Basically you'd be setting up some hardware that all of the people using your app would connect to in order to get the time. It may be more effort than you are willing to put in.
You'd need the following,
Some spare hardware (could be as simple as a computer running tomcat, or as complex as a dedicated server rack depending on how many people you think will be using your app.) or a subscription to a domain server/web host.
Some web service that just returns the time whenever an app requests it.
You'd need to make your server/webservice public, which is a whole other headache.
I'm not sure that would be your best solution either as it would depend on network connectivity to reach your dedicated server. There are a couple of alternate solutions you can try:
I don't know if your app is going to be public or used specifically for research. If it is the latter and it will be with a group of people you know and can coordinate with, I actually recommend that you just download ClockSync, sync up your phones to the same time server, and then execute your app.
If your app is going to be distributed to people you won't have contact with, then perhaps your best bet is to get your app to do a connection to one ntp server and grab the time that way. Here are a list of public ntp servers you can use: http://www.pool.ntp.org/en/
Here's some more information:
ClockSync
Sample code for making an SNTP connection
I hope that information can be of use to you in making a decision.
Hello
In my android application i would like to get Time since when the app is opened.
Initially what i tried was getting the time when the app is loaded from the server and then taking the difference with the current time from the device.But by doing that if the user changes the time then i willnot be getting the actual time.
Its not posiible to hit the server again for the same.
Is there any way to achieve this in android?
Please share your valuable suggestions.
Thanks in advance:)
Try the "SystemClock" class, "uptimeMillis()" method.
Store the result in a variable when the app starts.
Echoing what I said for your other question, you first need to become familiar with the activity lifecycle and understand the novel meanings (almost meaninglessness) of common words like "open" and "start" in the life of an android app.
There isn't any way you can prevent the user from changing the system time - you just don't have the right to do that to users. Normally this should be a rare event, unless you do something that makes them want to, such as lock them out of a free version of your app after so many minutes. (However if the phone is on a mobile network, presumably the mobile network occasionally adjusts its time to correct for errors in the device's oscillator, or administrative time changes)
What you can do is check the system time on every entry point to your application. If it ever goes backwards, well... something is going on. If the clock has been set back, you could assume no time between the calls with the negative time difference and resume your time meter from there, at least keeping all the previous used time in your record.
It may be that there are cpu cycle counters which you could query and correlate to system time, but this may be highly device specific and may in fact be resettable. And it may get weird if the cpu frequency is demand throttled.
You might be able to set a countdown timer as a bound on the maximum possible time between entry points at which you could meter. I don't know if these work reliably across system time changes or not - ideally they would. Testing or reading the source will reveal.
Use elapsedRealtime in your onCreate() store it. More reliable.