Know if uptime timer is reset or Android has been rebooted - java

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.

Related

Detect user change clock time after Force Stop app

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.

setExactAndAllowOnIdle doesnt trigger right

I have a problem using setExactAndAllowOnIdle. In my AlarmReceiver class I just show simple notification that shows when alarm was triggered and set another, same alarm but hour after.(currentTimeMillis + 60*60*1000). When my phone is in use application works fine, alarms come exactly on time. But when I let it work for few alarms without waking device up, they start to trigger with few minutes delays, or sometimes even exactly on time I wake up my phone.
You probably mean setExactAndAllowWhileIdle().
You didn't tell on which OS are You testing it but probably it's because of Doze Mode.
NOTICE:
Neither setAndAllowWhileIdle() nor setExactAndAllowWhileIdle() can
fire alarms more than once per 9 minutes, per app.
So You can't use this method to set every alarm what probably You doing.
For more information You can go here:
https://developer.android.com/training/monitoring-device-state/doze-standby.html

What happens with running timers when a system time is changed?

What happens with running timers when a system time is changed?
I have an android application and I use handler.postDelayed(Runnable,interval) to post a Runnable to be called (the run() method) at the end of the interval.
The question I have is:
What happens if the underlying system time is changed externally?
My impression is that the posting still happens but at the time of system time change the countdown starts again... Can anybody shade some light here?
Does the behavior change if the time change is forwards or backwards?
First,you should know Handler is based on SystemClock.uptimeMillis().
Handlers sendMessageXXX() methods such as sendMessageDelayed、sendEmptyMessage all use the method below internal:
//calcute the milliseconds we hope to handle the message since the system was booted
sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis)
Then,the time interval value SystemClock.uptimeMillis() + delayMillis will be kept into Message's field when,and we put the message into the MessageQueue waiting for Looper to poll out it.
While the looper gets the next message from the queue,it will compare SystemClock.uptimeMillis() with msg.when to judge whether the message is ready.If the next message isnt ready,it will set a timeout to wake up until the msg is ready.
Second,you confuse SystemClock.uptimeMillis() with System.currentTimeMillis().Below is part of the documentation of SystemClock which explains the two concepts:
SystemClock.uptimeMillis() is counted in milliseconds since the system was booted. This clock stops when the system enters deep sleep (CPU off, display dark, device waiting for external input), but is not affected by clock scaling, idle, or other power saving mechanisms. This is the basis for most interval timing such as Thread.sleep(millls), Object.wait(millis), and System.nanoTime(). This clock is guaranteed to be monotonic, and is suitable for interval timing when the interval does not span device sleep.
System.currentTimeMillis() is the standard "wall" clock (time and date) expressing milliseconds since the epoch. The wall clock can be set by the user or the phone network (see setCurrentTimeMillis(long)), so the time may jump backwards or forwards unpredictably. This clock should only be used when correspondence with real-world dates and times is important, such as in a calendar or alarm clock application. Interval or elapsed time measurements should use a different clock. If you are using System.currentTimeMillis(), consider listening to the ACTION_TIME_TICK, ACTION_TIME_CHANGED and ACTION_TIMEZONE_CHANGED Intent broadcasts to find out when the time changes.
No it doesn't matter. If you dig around the code, the delay is provided by the following mechanism -
SystemClock.uptimeMillis() + delayMillis
So it is purely relative. And changing of system time has no effect on it

Reliable "seconds counter" in java [duplicate]

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.

Handler.postDelayed not called when mobilephone in standby mode

I'm trying to write a simple app that should mute my mobile phone for a given time. It's my first Android app, but after many hours of reading I think it is nearly completed. But it still has one problem that I can not fix.
I'm using a activity to display the GUI. It has Buttons to set the start and end time, and everything else needed. When the user has entered all the parameters, they are passed to a service. This service uses a handler object, to register 2 callbacks (with Handler.postDelayed). One for start Mute and one for End Mute (in SetMuteIntervall).
The first tests seemed to work, but if I try to mute it for like 30 minutes, it never unmutes. I think it has something to do with the fact, that the mobilephone is or was in standby mode. I also tried to use Handler.postAt() but that didn't work either (and time relative to uptime was somewhat confusing).
So, what should I do to guarantee, that my callbacks are called, regardless whether the phone is in standby or not?
Here's the source of my program:
http://pastebin.com/XAgCeAq9
http://pastebin.com/33nepFV5
Try to use AlarmManager for planning some actions in future. AlarmManager is not standby-mode-dependend and will fire even if device is sleeping.
Your thread are actually stopped then the phone is in stand by mode. If you still want to use thread you can use WakeLock to prevent CPU from going to stand by mode (but still to switch screen off) but this is not the best way in your case.

Categories

Resources