Android - Implementing a means to get 'real' time in offline apps - android

Background
The company I work for is creating an app that collects information from various device events and sensor data.
One of the things we would like to be able to do is use time to process the data when it gets to the server.
We would also like there to be an acceptable amount of "offline time" allowed, i.e., the app could be used for its purpose even while offline until the next server data update is required etc.
Problem
One issue is that the user can just change the device time.
We overlooked this, and have been able to successfully generate events for the previous day, which would mean that our app could be fooled in situations where device time is a factor, which is very uncomfortable.
Imagined solutions
Obviously I can ensure that the app is always sync'd to the server before it starts collecting important data, and then use server time and make all further time relative to that.
Another way might be to keep a reference to something like the last update time or even the app install time and work out time relative to that.
Questions
How do people get around this typically?
Are there any libraries out there that can be used to enforce real device time?
Thanks guys

Related

Android: How to detect if user changes system time without running a constant service to check time

In my app I want to allow user to be able to use it for 7 days offline usage for free, but want him to connect online once 7 days are done and buy a subscription after that. So basically, I want to lock him out after 7 days from install. The problem is user can very well change system time and trick the app. Also, I cannot use server as the authority as the app is supposed to also work completely offline, except for the time of purchasing subscription.
I can run a background service to keep track of any system time change but I want to avoid doing that.
Is there a straight forward solution which can work even if the device is totally offline for 7 days.
You can save the current time in shared preference and compare it every time you sample it. If you get an older sample the user changed the time backward.
Use remote clock , for even simple read the time of server from mobile in desired time gap and use those number for your app's clock
So this is how I am planning to solve this, though this is not unbreakable but will work for majority of users.
So while signing for trial I get network time and store it as start_time in preferences. Next on each app start and app resume I read the current_time and write to prefs. Once current_time of pref is greater than time of device, we lock the app. Once preferences are not there we ask user to come online as suggested by #Zach
To make preferences editing a little inconvenient to the rooted device guys I am storing data in encrypted form in prefs.
This is still no way unbreakable as one can decompile the apk and read the obfuscated code to guess the algorithm and the key but I guess the value of content in the app is not that high for someone to go through that much pain.
can add syscall and track the time offline, get it from here

Get accurate time from android/iphone to server

We have an android(or iphone) client we are developing. The client allows the android user to send entries to a server which we also develop. If the client does not have data services (GPRS) at the moment the user sends the entry to the server, the client also supports saving the entry to an offline database and sending it later to the server.
One important aspect of the whole process is accuracy of the timestamps on which the user sent the entry to the server (whether the entry is made in real time or sent by the client from the offline database)
When available on the client, we get a GPS location and are able to use the GPS timestamp to send that to the server (or save the GPS timestamp on the offline DB and send it later to the server). However if the user has turned off the GPS (and all other location services), the device will not have a GPS fix and therefore the server can not determine accurately when an entry was made.
We can not use the local device clock as the user may change the clock to make entries on different times than they actually occurred (these entries are part of the users salary so he might have an interest to "fix" them).
So basically I am searching for a way to determine as best I can the time some entry was made when I can not trust the internal clock of the mobile. The algorithm should support both entries sent in real time or entries sent from an offline DB. the algorithm should also support cases where the user changes the time of the mobile, turns the mobile on/off, turns the GPS on/off while the application is running on the mobile etc...
Few ideas that I thought of:
Although I can not trust the mobile's time, it can still perform as a stop watch:
Have a class that will loop until the application exists, the loop will sleep 1 second and increase an internal clock variable by 1 second. On every GPS location my code gets we update the internal clock variable. This way I have an absolute clock that came from outside the device (from the GPS) and when the client sends an entry to the server, we can use the internal clock as an absolute time.
PROS: the user can not modify this clock as it is only updated when we get a location from the GPS
CONS: the application needs at least one GPS fix before the user can make any reliable entries
I can take advantage of the fact that the server has an accurate clock which is correct. If the client would send to the server info that the age of the entry is 10 minutes, the server could use its internal time and know the exact time the entry was made on.
The biggest problem is how to know the entry age? I thought about saving the entries to the offline DB with an age of 0, then every 1 second increase the age of the entry in the DB. The problem is that if the app is closed and/or the device is off this will now happen
This is where I am currently stuck. Any ideas on how to solve this are more than welcome
Thanks
Here's how I handle this issue for iPhone. When the app starts, I call my server and ask for the current GMT time (you could also call a public NTP server if you preferred). I then compare it to the system time. If it is different by more than X then I popup a message saying, sorry your system time is wrong so you can't use the app until you fix this. I then monitor for the user changing the system time while the app is running and if they do that, then I do the compare again (and popup the error message if the time is off by more than X). This ensures that their system time is always correct (within some reasonable allowance) and you can trust [NSDate date]. However, this solution does require a valid network connection. If this solution works for you, I can post the sample code.
i think i am going to combine Jules and Joel's answers into one solution which will provide for my needs the best solution:
since the user might change the clock when the mobile doed not have GPRS, just detecting the time change event will not help us as we can not validate at that moment the new time is correct.
As Joel recommended i will pull the time from my server when my application is started (at that point i still must have communications with the server or else my application will not start). The time pulled from the server along with the current device upTime will be saved.
when the user wants to make an entry i will calculate the current time using (Server Base Time + Current UpTime - Base UpTime). this way i will have an independent source of time regardless of the current clock of the device
this will defenitly work on android
on iPhone we will try to use something out of http://www.cocoadev.com/index.pl?FindingUptime to get the upTime
Jules & Joel, thanks for your answers!
Look into android.os.SystemClock. Specifically, elapsedRealtime() returns a time since the phone was switched on, which is not affected if the clock is changed by the user.
You can correlate times in event the phone is switched off by having code that runs when it is switched on and checks the realtime clock. As the clock can't be changed when the phone is off, I suspect you could use this to put together a system that will catch any simple attempts at cheating. (If the user roots the phone all bets are off -- they could modify the behaviour of the APIs from under you).
Running code every second will kill the phone's battery life. Most phones would be unlikely to last a day if you did this.

Android: How to add pw/security to the time/date settings of the phone to keep the user from changing it

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.

Android: real-time friend list update

I just made an app where a friend list is being updated in real time depending on if you get blocked or deleted by one of your friends, so I refresh the list on the screen. However, I was wondering what would be appropriate as the time interval for updates using threads? right now I am using 1 second but I think it's a bit exaggerated.
I would have it as user defined. If you set a default time that is unchangeable, some users may think it is running the thread too often. They may also think your app is causing bad battery life. Just have a few options like Twitter or Facebook. Something like 1,5,10,30,60,180,etc.

Time since the app is open in android

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.

Categories

Resources