According to Android Developer Reference uptimeMillis() returns the number of milliseconds since boot, not counting time spent in deep sleep. I checked the implementation of
uptimeMillis() in my code and it is roughly like this-
struct timespec t;
t.tv_sec = t.tv_nsec = 0;
clock_gettime(CLOCK_MONOTONIC, &t);
return (int64_t)(t.tv_sec)*1000000000LL + t.tv_nsec;
As far as I know CLOCK_MONOTONIC counts from some unspecified point linearly including sleep time.
Here are my doubts-
If CLOCK_MONOTONIC includes sleep time, how come uptimeMillis() doesn't take it into account? If my understanding is wrong and CLOCK_MONOTONIC doesn't take sleep into account, then what should I use to get system uptime including sleep?
What is deep sleep? Is the CPU idling referred as deep sleep?
What is the value of unspecified point in Linux? Can you kindly point out in code where this clock is started?
CLOCK_MONOTONIC stops when the system is suspended. Some people felt this was a mistake, and subsequently there have been patches for adding a CLOCK_BOOTTIME clock: https://lwn.net/Articles/428176/ . I don't know if these patches have yet been included in the mainline kernel. CLOCK_BOOTTIME is in ndk-9c - it only took 2,5 years ;) – Wojciech
Suspend, I guess.
IIRC some fixed time before boot. You'll find the exact value if you dig into the kernel source. Then again, the entire point about it being unspecified is that it could change at any point, so relying on it seems unwise to me.
Related
I found what was wrong:
So apparently http://www.epochconverter.com/ is makes assumptions of the precision of the input values, and from those assumptions values around 841073068 goes to 1996/1997. I'm not sure what is the assumption that leads to that exact date, but honestly I don't care.
Using the attached debugger I called new Date(System.currentTimeMillis()) and it correctly gave me a 10th Jan-1070 date, meaning the clock is not jumping out of the way like crazy.
Original question:
I'm running a single-board computer with Android for and IoT case (this https://developer.qualcomm.com/hardware/dragonboard-410c). The OS running is the plain vanilla Android supplied by Qualcomm.
Currently I'm testing the reliability of the board to be left executing for long periods at once and I'm seeing some very very weird behavior that I can't find an explanation for.
The board was powered up 10 days ago and it have no access to internet (WiFi is on but no access point setup and no Ethernet). The bluetooth is on and there're iBeacons and Eddystone in the office. Also there are WiFi in the area.
If I go now to Settings -> Date and Time, or check the notification shade or enter the clock app, or the calendar app, I see 10th of January 1970. Which is expected and basically showing for how long the board been running.
The app on it have an always running service, which does some data processing and some disk-logging (for debugging).
From the logs, I can see that System.currentTimeMillis() was returning an expected value when the board was initially powered on. That means, the beginning of the logs indicate an epoch time in January 1970.
But at the end of the logs (and also attaching the debugger on the live process), the value of System.currentTimeMillis() is somewhere in Sep/Oct 1996. Example values: 841073068, 841263234, 841579239
So my question is:
What is happening here?
Why System.currentTimeMillis() value changed and what could have changed it?
Why the Android UI (notification, clock app, settings) still shows me 1970? Where are they getting this value from?
edit:
There's been some confusion on the answers, and I can see my question was lacking the details.
I do not want to measure difference of time. I need an actual time stamp. Those values will be reported with bluetooth LE events via POST to our backend. This "no network" thing is a reliability test that we're running on the board, but we do expect to have network most of the time, and the boards should auto-update their times from network using the normal Android ways.
I'm just trying to understand on the current batch of testing, what went wrong and why.
Well, as you already know, the current system time (System.currentTimeMillis()) can be modified by any process if desired, it's perfectly be possible that it was modified by another process. It's not a reliable method to measure up-time.
I would rater use something like:
SystemClock.uptimeMillis()
Which returns the elapsed time (in milliseconds) since the device booted (not including time spent in deep-sleep).
I would also like to mention that I suspect that Bluetooth has something to do with it, I can imagine that Bluetooth uses the system time for pairing and security just like SSL does (but I'm no expert). GPS could also be a problem as GPS can be used to obtain an UTC time value, but I'm not sure if your board has a GPS module.
Regarding your edit:
Obtaining a valid time-stamp would be quite easy: server time minus the elapsed time reported by your board. But I suggest you either choose to accept the time reported by System.currentTimeMillis() or use the elapsed time instead. At the company I work we also work with embedded Android devices and on our server dashboard we can see both the up-time (up since) and the current device time, but they should not be mixed, at least in my opinion, especially since System.currentTimeMillis() is subject to changes and is affected by summer and winter time.
If you want to measure something, better try System.nanoTime(). Here is difference - https://stackoverflow.com/a/351571/2793494
Is there any way that I can, over a period of say a day, see how much CPU (or battery) each app uses? Here's a sample from BatteryDoctor app:
I think they did some works programmatically like:
Get CPU time of an app
Get Network Data Usage of an app
From that, they can "calculate" the battery usage per app (in percent).
I know there is some way to get the second work (Data Usage). But for the first one, seems like it's really hard to get.
I've found some ways, but they seems don't work
Tracking long-term CPU usage of apps in android (The "/proc/" + pid + "/stat" way)- I can't run this one, seems like toks[2] is always "S"
The command way ("sh -c top -m 1000 -d 1 -n 1 | grep \"" + pid + "\" ").
In anyway, it only can return the percent of CPU which app is using. But I want the time of CPU which app's used for a period (like 24 hours in the example).
So does anyone know how to get that CPU time per app programmatically ?
Or maybe it just the foreground/running time of an app?
Here's the answer to your question, but I'm unsure if it's really what you want.
If top calculates the %CPU of an app, let's call it %CPU_APP, over a window of, say 500ms, then the total time the app spends executing is 500ms*%CPU_APP over that interval. If you sum up all such intervals over, say 24 hrs, then you get the total amount of time the app used the processor in that period.
For example, say the window is 500ms and the %CPU_APP is 20%, then the app uses 100ms of that time. If the %CPU_APP is constant over 24 hrs, then the total time the app spends running is 24hrs*60min/hr*60sec/min*.5*%CPU_APP. (I leave the math to the reader ;-)> )
The difficult part is finding the size of the window. You might be able to measure this by eyeballing the graininess of the plot if it isn't given in any documentation. And the %CPU_APP is unlikely to be constant so you'll have to collect those statistics and integrate over time.
If this isn't the answer you want, please clarify your question and resubmit to stack overflow.
Short skippable intro:
I work at a rehabilitation hospital that's a couple kilometers from where I live. The hospital pays a bus service that picks the employees up at certain fixed locations. There's this bus driver, that picks us at 7:00. The guy is FREAKISHLY PUNCTUAL. I mean, this guy has to be in the tenth of a second order. The clock turns from 6:59 to 7:00 EXACTLY when he opens the bus door. And I was thinking of recording his punctuality for like 30 days and make a nice Excel spreadsheet for him. Error propagation and everything. He might even get a raise, who knows?
I'll make a simple app to save time in milliseconds, that seems easy enough, there're like half a dozen solutions for that here in Stackoverflow.
So, to the question:
I hit a button on a widget. It gets a time in ms. It saves it on a file (.txt, .csv, whatever)
How would you estimate the mean error of an NTP synchronized Android phone? What's the most precise and exact way to save a timestamp?
Thanks in advance
First thing that comes to mind is that time is relative, in the Einstein kind of way :) So if your reference is an Android phone synchronized with NTP, what is the driver's time reference? What if synchronization or timing somehow gets off, delayed on your phone and you have the impression that he's late one day, when in fact he's precisely on time relative to his reference?
But for the sake of solving the problem i think you can start by assuming he has the same time reference with you: some place in a network. I don't know the details of Android synchronization via time protocols, but i do know i built a so called Network Synchronization API. In your case i think my Java API might be of help. It tries to make a request for the number of milliseconds since the Unix epoch and then reads the response. The feature is that it gives you a framework on which you can estimate your true time compared to the server's by trying to discard network lag.
One thing to bear in mind: the solution above makes a request to my site (a.k.a. GoDaddy servers) which is probably different than the network location Android phones sync with. Feel free to change the request location.
Second thing to bear in mind: this rabbit hole goes deep :) No measurement can be perfect. You can try to achieve human / reasonable precision but it can never be perfect (e.g. there are other unknowns: what if there's a lag in your Android CPU just as you press the button, or what if your own reaction takes a few milliseconds? The moment you press the button is not the same as the moment the doors actually open and my impression is they're at least a few millis apart)
I'm writing a sports app that needs to track the elapsed time of quarter/half/period. Elapsed time needs to be accurate to the second. The game clock needs to continue to run even if the user explicitly places the device in sleep mode by pressing the power button.
My first attempt at this involved using Handler.postDelayed() to trigger the clock ticks every 200ms and WindowManager.LayoutParms.FLAG_KEEP_SCREEN_ON to ensure that the "clock" wasn't stopped by a screen timeout. But I soon learned that it was possible to circumvent this approach by pressing the power button to manually put the device to sleep. In addition, the postDelayed() approach is experiencing some clock drift, apparently a result of the time spent in the run() method. The actual numbers are still accurate, but instead of being aligned, for example, on 5 second boundaries which are easily understood by users - the timers involved start to drift, resulting in some understandable user confusion.
After a bit of research I found techiques for using services, java timers, AlarmManager, and PartialWakeLock to implement timers. Services by themselves won't solve the problem associated with the device going to sleep. Java timers, like services, don't solve the problem with the device going to sleep. AlarmManager seems like a good approach, but I'm concerned that this isn't an appropriate use of AlarmManager (i.e., very short intervals between alarms). Using PartialWakeLock also looks promising, but by itself it doesn't address the clock-drift problem I'm experiencing.
I'm going to try a combination of AlarmManager and PartialWakeLock. The idea is that AlarmManager will help combat clock-drift and PartialWakeLock to help keep the code simple (fingers-crossed). I'm hoping that this approach will result in a reasonable balance between power conservation, code complexity, and user expectations. Any advice is greatly appreciated.
Thanks,
Rich
I've got a partial solution to my original post above. It doesn't yet address the clock drift associated with the time spent in calculations during the postDelayed() processing, but it is a step forward. In addition, it's deceptively simple, always a good sign.
It turns out I was using SystemClock.uptimeMillis() when I should have been using SystemClock.elapsedRealtime(). The difference between the 2 is subtle, but important.
As you might expect, my solution keeps track of elapsed time by accumulating durations between calls to postDelayed() - i.e., elapsed time = elapsedTime + lastClockInterval. As stated above, the original implementation used uptimeMillis(). Careful reading of the javadoc reveals that uptimeMillis() doesn't include time spent in "deep sleep", e.g., when the user presses the power button. But the elapsedRealtime() method does include time spent in "deep sleep" mode. All that was required to track time across deep sleep cycles was to replace the use of uptimeMillis() with elapsedRealtime(). Success! No need to use AlarmManager, PartialWakeLock, or anything else substantially more complicated. Granted, these methods still have uses, but they are overkill when implementing a simple elapsed-time clock or timer.
The next problem to tackle is with the clock-drift caused by the non-zero execution time associated with postDelayed() processing. I'm hoping that spawning a thread to do the processing will address this issue, allowing postDelayed() to more or less mimic an asynchronous call. Another approach would be to adjust the postDelayed() delay time to take into account the time spent in postDelayed(). I'll post my results.
On an unrelated note, during my investigation I treated myself to a CommonsWare Warescription. While I didn't directly use any ideas from this source for this problem, I do think that it is going to be my Android go-to information source for the foreseeable future. I've got an O'Reilly subscription through my day job, but I've found the CommonsWare books to be as least as good, if not better, source of information about Android development as the O'Reilly resources. And I have found the O'Reilly Safari resources to be pretty good. Interesting...
Cheers,
Rich
I'm sorry this is not quite an answer, but I feel your process is similar to mine, but there was little in regards to code to make it clear how you got around the sleep issue. I don't have drift, but the app does hang when it goes into sleep mode,then kind of resets forward when the display is active, then hangs again when the device sleeps. This is the core of the timer process.
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
#Override
public void run() {
// do something here to display
processTime(); // process what to be done on a sec by sec basis
try {
timerHandler.postDelayed(this, 1000
} catch (Exception ex){
}
}
};
Is there something here that I can do to allow it to continue when in sleep mode? This use to work on older version of android/devices.
The description for the method uptimeMillis says:
Returns milliseconds since boot, not
counting time spent in deep sleep.
Note: This value may get reset
occasionally (before it would
otherwise wrap around).
How often might this happen and (more importantly) will it affect runnables that should be executed by Handler.postAtTime?
The uptimeMillis call grounds out in systemTime(), which on a Linux system turns into clock_gettime(CLOCK_MONOTONIC, struct timespec *).
The struct timespec holds seconds in a time_t, which appears to be a 32-bit value. If it starts counting near zero, you will not likely be alive when it wraps.
If you need more specific details, you should investigate the behavior of clock_gettime(CLOCK_MONOTONIC) in the Linux kernel.
If you happened to call uptimeMillis right when it wrapped, then yes it would affect your postAtTime call.
A signed long in Java has the range:
-9,223,372,036,854,775,807 to 9,223,372,036,854,775,807 (~9.2E18)
9.2E18 milliseconds is 292,277,266 years. If you are working on a space probe, you probably want to take this into consideration, otherwise you can probably get away with assuming it won't wrap in your lifetime.
The kicker for me is that the Android documentation for uptimeMillis claims
This clock is guaranteed to be
monotonic . . .
Then soon after they say that uptimeMillis will be reset due to variable wrapping - the exact opposite of a monotonic clock!
I was using it for a service and did not ever see it resetting. I would really assume it won't.
The problem with postAtTime() is that it will not be called during sleep (since uptimeMillis() will not update). If that's an issue, then I would use some other method.