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
Related
My customer make a request for their commercial app is to automatically expire the content after downloading into the device in 7 days, even in the following cases:
+ without the internet connection to connect and check the expired time from the server
+ stop the customer try to maliciously modify the time in their device to expand the expired time
When the content expired, it will be removed from the device and unavailble to watch any more.
After a few days researching on Google, I still not find out the appropriate approaches.
Why can't you just add an expiration date at the content when you download it? And then check if is expired or not locally, without any control server-side.
There is a few suggestions but not of them is enough to cover all the cases maybe it will be useful if you combined them :
1- get the time based on the last know-location .
2- get the network time so the user
changing their device time wont matter (requires an internet
connection)
There isn't a great solution to this. You do have a couple of options, none of which are perfect.
Option 1 - use date / time from last known location
This will require you to request GPS access in your application, which may concern users, if the app doesn't have a valid need for tracking the users' locations. But basically get the last known position, and in the Location object returned would be the time as of that last location check. Two things could prevent this from working 100%. First, with newer version of Android, users can disable certain app permissions. This means they could disallow GPS access to your app. To combat this, you could check this on app startup and inform the users they cannot access any content unless GPS access is enabled. Second, if the user has no GPS signal, the last known location may have been from days ago, meaning the "current time" will be frozen as of the last GPS signal. Also, some devices don't have GPS chips, so this would not work for them.
Option 2 - Try to detect system date / time changes by keeping a log of the date / time in your app.
Basically, this will take some work to keep track of the system date / time on each launch, as well as the duration of each session in your app. With this log, you could compare to the current / date time and see if the user is rolling back the clock. This wouldn't be perfect, as a smart user who understood your checks could roll it back to the closest time to the last time the app was shut down, but at least this would limit them to having access to the content for 7 days of run time. Also, it would take a really dedicated person to keep track of / exploit your checks. Most users would simply try to roll back their clocks to a past date and it would be simple to catch. With this method, make sure you are capturing / storing all times in UTC time, so that time changes don't trigger a false fraud scenario.
Recommendation
Personally, I would use both options if you are OK with the GPS permissions on your app. If available, and given permission by the user, use the last known location to get the time. If that isn't available, or if the user has removed the permissions, use a local store of run date/times and durations as a fall back.
This is more of a "is this valid" type of question than "how do I do it", since my coworkers want a second opinion on it. We want to have an accurate timestamp of the time user takes a picture using our application, and the stamp should be something that our users can't influence. Since we want our application to work even though there's no internet connection, just asking the time from a server won't work.
I've currently done this so that the application asks a timestamp from the server, and at the same time takes note of what time Android's elapsedRealtime() clock has at that point. When user takes a picture, the software checks the elapsedRealtime() again, and then calculates the timespan between the two points of time saved from elapsedRealtime(). That timespan is then added to the timestamp gotten from the server, so that we'd have the time that represents the user's current time.
In the abstract level, does this sound like a valid solution that gives accurate time everytime? Are there other solutions to do this?
EDIT:
A requirement I forgot to mention: the pictures can't be lost even if the phone is turned off before sending them to the server, nor should the timestamp lose validity because of that.
Thanks in advance,
Xevas
If it is absolutely imperative to get this time correct, you could start a timer when the user takes the first picture and then when you get internet access, check time on the server and calculate the time when the picture was taken by subtracting the time elapsed since the timer was turned on from the current time.
I want to know if the user is away for some amount of time. (and then do something according to it.) I cannot depent on screen sleep because user may have disabled it or its value may be greater than timeout of my application.
is there any information like (last user response time ) in android operation system ? and how can i get it?
last user response time = the last interraction time between the user and the phone.
p.s.:i am targetting android 1.6
No, there is no way to tell when was the last time the user interacted with your application in the SDK. You'll have to do something by yourself.
High level explanation of a simple solution:
Assuming you use some base activity inherited by all activities, you can log the current time in your BaseActivity.onPause method. Save it in the app preferences or in a database. When your initial activity starts (onResume) read the same value and compare it the current time.
You can also use Activity.onUserInteraction but saving to preferences/database everytime this is called will considerably slow down your app / feel less responsive!
My app will have a 'clock in' in the listview. As a user will click that item it will grab the time/date from the phone itself and send that data out to the server. I prefer doing this over using server time since if they dont have a signal/reception they wont be able to clock in. I would like to add a password security to the time/date settings itself so the user wont be able to take advantage of changing the time when clocking in. How can I make that happen?
Thanks
I don't think you can do that, but you can cross-check the time.
When you "clock in" also open /proc/uptime as a text file and read the value there. I believe it is in seconds. When you clock out, re-read the value and use the difference as a cross-check. If a server is also available, check the time from the server too (or report the clocking in immediately)
If the phone crashes or is powered off in between, the difference in uptime could be less than what you've recorded via the ordinary clock. In that case, the difference in uptime might be less than the ordinary clock (likely it will be negative) so if your clock-in was done without access to network time your software may have to have a way to report that particular result as unverified, and track the number of unverifieds per user to flag for human review if it becomes excessive.
A user could conceivably compile and install a kernel that lies about uptime, but that person could probably get around most of the other things you would do, too.
I would suggest to just send message to server "user X wants to clock in". And server will use its local time for "clocking in". This way you will completely ignore device's time, and have more control over your infrastructure.
In general, if you want something to be as secure as possible, don't do this on the client side (unless you absolutely have to). And in this case user may gain root on his device and use some command line magic to fool you server with fake date/time. Its not that hard. And you just won't be able to predict all the smart workarounds of you "time protection".
You could set up a service to run every minute (or so) that checks the time. If the time is not ~1 minute after the last check then it may have been changed. You should confirm with the server at this point to make sure the discrepancy wasn't caused by rebooting the phone.
If you find that the time was changed, you can change it back or log this with your main application and flag the "user" for disciplinary actions.
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.