I want to show seconds in a watchface. In normal mode as well as in ambient mode. General Handler thread Handler handler = new Handler( /* Runnable{ invalidate(); handler.postDelayed(this, 1000);}*/ ) Works fine to update time and show it in screen while in normal mode but it sleeps and slips so far away and executes in random time while in ambient mode. Well this is nothing new and android doc and everyone says to update screen in every minute instead of a second. But I want the watchface to show seconds and that should be updated in every seconds despite battery life. And I can not find a answer for this.
I definitely tried ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();. All gave similar result and among these ScheduledExecutorServices schedule at fixed rate method gave worst performance. In my opinion AlarmManager is overkill for this purpose. The thread is created in onCreate method and is not changed.
Now someone please tell me a way to update the screen in every second while in or out of ambient mode.
Note: All thread works fine on wear OS emulator but on actual watch it shows this behaviour, that is executed in a random time, like in every 20 seconds.
Related
In our Android app, we have UI component and core C++11 module. A thread is running based on std::chrono::system_clock::time_point, such as below:
while(this->m_ConditionVariable.wait_until(lock, this->m_Object.to_time_point())
== std::cv_status::no_timeout)
{
// ... handle any notify() or arbitrary sleep breaks
}
Execute(); // <--- not being called consistently
Now, we are testing with 1 minute time_point. If the app is in use, then the Execute() is invoked as expected. However, if the app is moved to background or if even the screen is locked, then the Execute()-s behavior is not consistent.
Sometimes, it may work properly every minute for 15 mins and after that it will be invoked after 2 minutes or 3 minutes or 10 minutes, instead of fixed 1 minute. Using debugs, we checked that, the time_point supplied is proper.
Suppose if we run the app in debug mode (using Android Studio) then it works fine even in background and screen locked mode.
Does Android have any threading priority for the app running in background?
Update 1: Basically the background thread is collecting location information. I came across below question, which suggests that in Android, when the phone is locked, the thread execution is halted. Am I stuck to that problem?
App seems to stop working when the screen goes to sleep
Update 2: With partial Wake lock, it works fine. But not sure if that's a good solution. If that's the only way, then I would appreciate strategy for how to use it optimally.
Update 3: If I replace wait() with smaller sleep(), then it works fine even without any Android wake lock. However we are yet to do regressive testing on it.
When the device is idle, the CPU is stopped and any thread running is paused (C++ or Java). If it wakes up for any reason your C++ thread will start working again, hence the random behavior: Other apps or services might wake-up the device every now and then.
Adding a partial wake lock works in your case but that will prevent the CPU from going idle, which will cause some battery drain. If you don't care you can use this approach, if battery live is an issue, you can use the Java alarm API to wake up the device on a regular basis. Then the java API can call the C++ code through JNI.
Android documentation for repeated alarms: https://developer.android.com/training/scheduling/alarms.html
For the update 3, using a small sleep rather than wait(), I suspect android is not going in idle mode while a thread is running, maybe it waits for a small timeout without any thread active before it goes idle. This approach will have the same effect on the battery drain than the wake lock.
I's like my Android app to close down after a period of disuse. Without screen rotation, I've easily implemented a solution with Timer/TimerTask. Alas, when the screen rotates, everything is (understandably) messed up.
The time out period is typically 10 minutes and the user has to be able to reset the clock to zero at anytime, invoking another 10 minute period.
So what's the preferred approach to do the timing in the background, be able to reset the clock, and ultimately receive a shutdown notice, despite an occasional screen rotation? I've looked at IntentService, but don't see how to reset the clock, or know the preferred way of getting the shutdown notice back. And everything must be set up so that access to the timer is available after the app reconstruction on rotation.
Thanks,
Chris
This is seems trivial but for the life of me I can't figure it out. Here is the scenario:
MainActivity starts with FLAG_FULLSCREEN, FLAG_SHOW_WHEN_LOCKED, FLAG_KEEP_SCREEN_ON, FLAG_TURN_SCREEN_ON and shows a TextView and sets SCREEN_OFF_TIMEOUT 1000.
In onResume I want to set a timer for 10 seconds using Thread.sleep(10000).
After 10 seconds I want to start another Activity that is similar except I clear FLAG_KEEP_SCREEN_ON and FLAG_TURN_SCREEN_ON to timeout the screen in 1 second. I basically want to go back to Sleep.
Again, I set a timer for 10 seconds. Then I want to go back to MainActivity and wake the phone again and cycle.
My problems: Using Thread.sleep doesn't allow me ever see MainActivity. So I put it in a thread. Same for ResumeActivity. But then the behavior becomes random, sometimes turning on the screen, sometimes not, sometimes running onResume more then once. Sometimes Thread.sleep doesn't work but no exception.
My goal is to simply alternate between wake and sleep at an interval using a fullscreen Activity over the lock screen. WHY? (I know some will ask) I want to make a timer that doesn't stay on for the entire duration (say 1hr) but just shows the timer every few minutes to save battery life.
Thanks in advance!
UPDATE: I found part of my problem. I guess android doesn't like threads sleeping for 10 seconds. If I set the thread.sleep to only 5 seconds then it will switch fine but not recognize the flags (the screen never turns off). So I need an idea for triggering a timed event.
UPDATE2: Ok, I discovered postDelayed to deal with timer, but seems that android cannot go to sleep in less then 15 seconds and acts weird when you have events occur during going to sleep. After setting my timer to 20 seconds everything works but won't sleep any sooner then 15 seconds. Any ideas on making android go to sleep immediately without becoming a system app?
FINAL PIECE: Any ideas on how to make
I need to execute code at intervals, sometimes 10 seconds, sometimes 5 minutes. The code should be executed at exact 10 seconds from start, then at exact 5 minutes and 10 seconds from start, etc.
A Chronometer is ticking along from the start, so the execution time must be accurate.
Using Handler.postDelayed does not work, because the code to execute could take some time. The next execution of the code could be late when that happens.
When I wanted to implement AlarmManager, I saw the note
The Alarm Manager is intended for cases where you want to have your
application code run at a specific time, even if your application is
not currently running. For normal timing operations (ticks, timeouts,
etc) it is easier and much more efficient to use Handler.
So I'm a bit confused, how should I do this to guarantee correct execution?
As Chris stated, there's no such thing as exact timing in Android.
But you could try it like this to come near realtime...
some Pseudocode for waiting 5s:
class mJob implements Runnable{
public void run(){
while(System.currentTimeMillis()<myExactTime){ //poll for your time
Thread.sleep(1);
}
//Ok, we are as near as we'll ever get
//call here your 'realtime' function or whatever you need
}
}
mHandler.postDelayed(mJob,4950); //the closer to 5000, the better for the cpu but you could miss your `myExactTime`
I don't now how exact this is, you'll just have to try it. But I see no other way to become more 'realtime' with the normal SDK. You could even remove the sleep(1) to become even closer to your myExactTime.
For the next call use something like this (scratch):
nextCallDelayInMillis = starttimeInMillis+No1_Delay+No2_Delay-System.currentTimeMillis();
Have a look at this post : Time/Date change listener. you can use setRepeating() method, or alternatively set the timer again after each execution.
As android is not a hard-realtime OS, exact timing of execution is not possible without substantial kernel modifications. Even there, you are unlikely on a typical android device to have much in the way of exactly timed means of useful I/O, so just running your code at the perfect time may not be enough.
At best you can determine using the more reliable of the timers the latest point at which your code could have run, and take after-the-fact compensation measures.
In terms of the available timing methods, a major consideration should be if you intend the device to wakeup from sleep to accomplish events, in which case you should use the Alarm Manager, if you intend to keep the device awake, in which case you should use a Wake Lock, or if you are okay with your events happening only when the device is awake and your service or activity is running, in which case you can use a simple Timer.
You didn't specify if your code runs while application is running or as background service. It's important, because after you lock your device, Android goes to sleep mode, where CPU is off and functions like postDelayed wont be activated. Intents asking to start activities too.
But AlarmManager broadcasts will.
I'll quote from here
The AlarmManager is best used for tasks that need to
run even when the application isn’t open. For normal timing operations
that need to run during application use (ticks, timeouts, etc), it is
more efficient to use the postDelayed() and postAtTime() methods of a
Handler. The AlarmManager requires too much overhead to justify it
being used this way.
I suggest you to use postDelay, for any post to handler, handler is opening new thread and code is executing simultaneously.
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
//some code
mHandler.postDelayed(this, 1000);
}
};
Here is my complete code I used postDelay for displaying count down timer: https://github.com/minimaldevelop/antistress/blob/master/src/com/minimaldevelop/antistress/AntiStressExerciseActivity.java
Also here I using AlarmManger but only as remainder to display message at notification bar when application is closed.
I'm making an app that starts a Service that sends SMS message periodically under specific conditions. It all works, but I have problems to run the job (check conditions + message sending) periodically every minute when the phone is in "standby" (display turned off). With screen on it all works without problems.
I tried using java Timer and TimerTask, but when the screen is off nothing works and when I turn it on, all skipped task are executed in a row (for example, if I turn off the screen at 20:00 and turn on it at 20:30, TimerTask is executed 30 times at 20:30).
I tried also with Handler using Handler.postDelayed method. In this case nothing is done, and when I turn on the screen skipped task are not executed.
So, how can I run a Runnable every minute also when device screen is off???
You can try the AlarmManager
http://developer.android.com/reference/android/app/AlarmManager.html