This question already has an answer here:
I want to get current time in Java but without the Internet and without the system time
(1 answer)
Closed 6 years ago.
I am new here:) I am developing a small app in android (java) and I need something to control the seconds elapsed between two events.
The problem with System.currentTimeMillis () is that the user of the device can change his system date for example after the first event, and so when I take the value returned by System.currentTimeMillis () after the second event, and I make the difference between the two values, this obtained difference is not valid at all.
Another option I tried was System.nanoTime (). Although the user changes his system time, the seconds count is valid. But here the problem is that if after the first event, the user switches off the device, the value returned by System.nanoTime() after the second event is not valid because with the device restart, the counter of System.nanoTime() also restarts , and therefore, the elapsed time is again not valid.
Does anybody know any method to count the seconds between two events, considering user date changes and user restarts of the device ?
Thanks in advance!
Since you want to avoid the errors that can be introduced by the user messing up with the system date, you cannot rely on that source for information. A reliable time (and accurate, if matters) can be obtained using the NTP (Network Time Protocol) protocol. Take a look at this question for more details about it: Java NTP client.
An alternative you may consider is, instead of finding a reliable clock to compute the date/time difference, you can check if the user has changed the system clock. A simple way would be to store the timestamp and check periodically (every second of so) if the new timestamp you get from the system clock is smaller (before) the previous one. If so, you can take action.
Related
I need to do a count down timer for 24 hours but the timer needs to give equal time to all users and simultaneous.
Nobody here can really help you too much because the question is very vague and there isn't much for us to work off of, but I'll give answering it a shot and we'll see how that goes.
If I am correct, you're asking how you can make your program show every user the same timer. To do that you're going to need a server with the timer information. Each user's program should send a request for the timer information to the server whenever it needs the information and then your program does what it does with the information.
You don't even really need a timer for that. You just need to post the exact date/time of the event on a web page. In the app, on app start-up, it reads the date of the event from your web page, converts it to a Java Datetime object, then gets the current Datetime and does a date diff compare, to display how long until the event date/time. If you wish, you set a timer in the app, and every second or minute you get the current time again and update the date diff display.
There is a game where 10 minutes of real life equals 60 minutes on his day. So one day in the game equals 4 hours in our real time.
The user will inform me of the time of his game on his first time in the application, and I will need to show the game time to the user every time he enters the application. I tried doing this using a SensorService and a BroadcastReceiver, so that the calculation was always being done.
But since there is no way to get this time the same way we get the normal time, I had to do Background calculations to keep the time counting. This brought me trouble because the time was NEVER displayed accurately, not to mention the problem that is when the user has their cell phone turned off and everything.
I would really like to know if there is a simpler way to do this on Android, I'm new to this area and I do not know if there is a custom speed-time format or something. Thank you all at once.
save the first launch time(normal time).
on succeeding logins game time=(System.currentTimeinMilis() -first launch) * 6
I can detect change clock time when app in foreground, background, or kill from Recent App by using android.intent.action.TIME_SET follow here.
However, if I Force Stop app in Setting->Apps I can not receive this broadcast anymore.
Currently, I want to detect user change clock time come back to my app after ForceStop so I do
long deltaTimeBeetweenCurrentTimeAndTimeSinceReboot = System.currentTimeMillis() - SystemClock.elapsedRealtime();
long oldDelta = mSharedPreference.getDeltaTimeBeetweenCurrentTimeAndTimeSinceReboot();
if(deltaTimeBeetweenCurrentTimeAndRebootTime - oldDelta > 5000){
// clock time change
}
Idea is I saved a delta between currently time (System.currentTimeMillis()) and time since reboot (SystemClock.elapsedRealtime()). Every time I open app, I will compare oldDelta and newDelta (except the first time install). It work well in case: User Fore Stop app->Change time->come back to app.
However, there is still have 1 case that is: User Fore Stop app -> Change the clock time -> Reboot device -> Open my app. At this time I can not use the above method to check the clock time have changed because after reboot the SystemClock.elapsedRealtime() will reset. How can I detect clock time have changed in that case?
Any help or suggestion would be great appreciate.
Few months ago I was in pretty the same situation. I didn't find any answer to directly solve the case, so I won't help you with it. But I can give you kind of advice:
Look at it with a different point of view.
What I did in my case, I answered myself to questions:
"Do I really want to know that user has changed the time - because I implicitly inform/present the fact to user?"
OR
"Do I want to know that user has changed the time - because I need it to invoke some actions or calculations in the application background?"
In my case I had NO-YES answers. So, for problematic case of Force-Stop + reboot I assumed that the time could had been changed and I reset my application's time configuration likewise the first app launch.
Let me know if it helps you anyway.
It would be hard to implement without external etalon (backend is the best option). You may save time a user force to stop the app and when the app alive again compare with some predefined delta (time window). If you get a "big" difference consider the user is cheating.
You may also play with timestamps of the filesystem to define some inconsistency.
I want to disregard the Device Time and want to implement my own Clock inside my app. The time I need will be coming from the server.
I have already set its Date and Time as follow:
Date.setDate()
and
Date.setTime()
Now, I just need to get my private Date running like a clock.
How can I do this?
EDIT:
So far, I have not implemented anything as I have no idea on how to create a clock/timer starting on a specific date/time object. I am thinking of having a thread and a runnable for ticking but I don't know how to increment it to make it work just like a clock.
I have a independent clock created in my application. The clock runs as a different thread in the activity, starting from a base time set by me. I update the clock using the difference between the uptimemillis when I set the clock, and the current uptimemillis. But the uptimetimer, can be reset by Android, and is ever reset when Android reboot.
I only want to know if the uptime timer is reset, to know if the clock is still reliable.
How?
According to the documentation you can use SystemClock.elapsedRealtime()
elapsedRealtime():
Returns milliseconds since boot, including time spent in sleep.
This value will only be reset when the device is restarted. Listen to the broadcast boot_complete and you will know when that is.
The problem with the updateMillis() is clearly noted in the documentation:
uptimeMillis():
Returns milliseconds since boot, not counting time spent in deep sleep. Note: This value may get reset occasionally (before it would otherwise wrap around).
From how I understand the documentation, by using elapsedRealtime your users cannot manipulate your counter.