Does anyone know of a way to get the time the device has been in sleep? I am trying to get Awake Time for the device battery and I can get the total time since boot using SystemClock, but they do not have a method for sleepTime. If I could get sleep time, I could do totalTime - sleepTime and get the awakeTime, but not sure on how to get sleep time.
Any suggestions?
Thanks
SystemClock.elapsedRealtime() is "the time since the system was booted, and include deep sleep".
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."
Hence, SystemClock.elapsedRealtime()-SystemClock.uptimeMillis() should be the amount of time in "deep sleep".
Related
I'm trying to collect accelerometer values at 50ms period and do something with collected values at every 1 minute. So i used alarm manager with 1 minute pending intent with RTC_WAKEUP flag and set sensor event to 50ms. It first seemed that sensor event was called well with exact time period and collected 1150~1210 accelerometer values at every one minute passed even when my device screen is off, but when i unplugged my device from computer and turn screen power off, it started to become slower, at the end it collected only 60~100 samples at every 1 minute.
So i currently acquire Wakelock whole time and replaced alarm manager with timer to do timer taske at every 1 minute. But i'm worried of drain of my battery.
So what i wanna ask you are below"
1) Is device awake when device is plugged to computer or recharger?
2) What method would be better for battery life? Using alarm maganer to acquire wakelock every 2 second to stay device awake and do something when it reaches 1 minute? Or using current method of acquiring Wakelock for whole time to make device alive and use timer to do something every 1 minute?
I found that phone is alive only when it is plugged to computer. After unplugged from computer, phone slowed collecting sensor values few minutes later. So i changed my AlarmManager to fire alarm intent every 2 second to do both timing task and keeping device awake. But phone sometimes didn't fire alarm intent every 2 second at exact time, which was critical to purpose of my application. So i changed method to keep phone alive from using AlarmManager to just hold Wakelock whole time and used Timer and Timertask to do timing task. After timer did all timing task then it release wakelock. Code inside sensor event only collect sample and put sample into queue and in timer task at every 2 second, it transformed collected samples to frequency domain using fft, which needs a lot of calcultion.
I read many posts that holding wakelock is really inefficient when it comes to battery life. But when i hold wakelock, i checked cpu usage during each timer task and sensor event being processed, each 2 second and 50ms period. It used only like 0.71~1.75 % of total cpu usage every second!! Which i thought not that bad for battery life. So then i tested again by holding wakelock for 7 hours with same period for timer task and sensor event. The result was that it used less than 10% of battery, and collected sensor values samples almost exact every 50ms and also timer task at almost exact every 2 second!!
I antipated more battery usage because of weight of the code in each timer task and sensor event. I'm happy to know that if i carefully design timing task code, it is not that bad for battery life even though holding wakelock and keeping cpu of phone alive!!
I'm developing an app that need to know the moment when the system startup, periodically.
I use System.currentTimeMillis(); to get the current "date" in millis.
I get the system elapsed real tine with SystemClock.elapsedRealTime().
I subtract the total time with the elapsed time, and I retrieve the system bootup time.
I would understand if the value change of milliseconds over time(different times in executing instructions). But for me it changes of seconds!!! Is very strange.
Someone have an idea of why?
Differences of seconds (or even tens of seconds) should not be surprising. "Current Time" corresponds to what the user perceives from the clock displayed. If you watch the displayed clock, it will not always change immediately. Read the docs:
http://developer.android.com/reference/android/os/SystemClock.html
It's pretty clear that you can't depend on currentTimeMillis for much of anything where you need millisecond accuracy. However, in most applications you really don't need that level of accuracy...
If you are trying to determine "exact boot time" from a specific moment in time later, a few seconds probably is the best you will do. Besides, what qualifies as "booted"?? When the kernel is loaded? When the user can interact with the device? When the device screen lights up? When the device can actually be unlocked?
You should probably just listen for RECEIVE_BOOT_COMPLETED (Android - Start service on boot).
Here is the Android doc: http://developer.android.com/reference/android/Manifest.permission.html#RECEIVE_BOOT_COMPLETED
When I press the sleep button on the device then turn it back and "update" the uptime shows the time as if the device did not go to sleep.
From Android Reference: 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. Most methods that accept a timestamp value currently expect the uptimeMillis() clock.
Standard functions like Thread.sleep(millis) and Object.wait(millis) are always available. These functions use the uptimeMillis() clock; if the device enters sleep, the remainder of the time will be postponed until the device wakes up. These synchronous functions may be interrupted with Thread.interrupt(), and you must handle InterruptedException.
--
Seems like your phone is idle or power saving and not technically sleeping...
Assuming the button you are talking about is the "power" or "lock" button, that isn't necessarily putting the device into deep sleep. In fact, looking at the definition of deep sleep (when the uptime counter will stop) I think it would be very rare. The phone will almost certainly keep the CPU running at a low level to monitor for alarm timers and other system scheduled events. If you are wanting to monitor how much time the phone is in "sleep" (screen off, phone locked etc) I suspect you will need to register a broadcast receiver and monitor for those specific events.
take a look at this thread Android - how to receive broadcast intents ACTION_SCREEN_ON/OFF?
also take a look at the power manager
System.currentTimeMillis() is giving wrong time.
It returns time values from 1980
Also time value taken through this function differs from actual time sometimes.
Some sample values returned by the function
315977198121
315965244789
316002166580
315982533137
Yes, time returned by System.currentTimeMillis() can jump around, for example because the device clock may have drifted, and is being reset due to fetching an accurate time from the network
Time as observed through other APIs may also jump around even more, for example due to changing time zones, or due to daylight saving.
(However that doesn't explain why you are seeing times suddenly in the 1980. That frankly sounds like a device error.)
You state that you are using the value to get a duration. That's an error - you should be using SystemClock.elapsedRealtime() for duration calculations.
See the docs at SystemClock, which specifically note:
Three different clocks are available, and they should not be confused:
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.
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. Most methods that accept a timestamp value currently expect the uptimeMillis() clock.
elapsedRealtime() and elapsedRealtimeNanos() return the time since the system was booted, and include deep sleep. This clock is guaranteed to be monotonic, and continues to tick even when the CPU is in power saving modes, so is the recommend basis for general purpose interval timing.
Try using System.nanoTime() instead of System.currentTimeMillis().
The documentation of System.currentTimeMillis() seems to indicate that it shouldn't be used for calculating time elapsed!
you can create broadcastreceiver on action 'android.intent.action.TIME_SET'. You can know when time on your device change (by another applications).
When testing our game, that is heavily dependent on System.currentTimeMillis(), we are experiencing an annoying bug.
Our game uses an array of delta timestamps that indicates when certain things should happen. These timestamps matches a piece of music that is being played.
Testing at home gives us no problems at all. It's impossible to reproduce the bug while testing from our home.
But testing while driving around in the car, between cities, gives us sync problems between the timestamps and the music. My best guess is that Android freeze up the system, including the system timer because it's switching network, or looking for a signal?
I've tried inserting a fake hick-up in the game, by making the thread sleep a few seconds when I press a certain button. This freezes the screen (obviously), but everything is still syncing fine when the sleep is over.
The only way to reproduce this bug, is to take a trip by car or bus or train - which of course is most probably where most people will be when playing our game.
The question is of course,
what to do about it?
Does anyone have any ideas?
Read SystemClock.
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.
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.
I think it's better to use System.nanoTime().