What my code does: My activity has a CountDownTimer
that starts when a user presses a button. When it completes, a sound is played. Here's the code:
public class PrepTimer extends CountDownTimer {
public PrepTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
@Override
public void onTick(long millisUntilFinished) {
updateSessionRemaining(millisUntilFinished);
setPrepDigits(millisUntilFinished);
}
@Override
public void onFinish() {
session.setPrepRemaining(0);
playSound();
}
}
What I'd like it to do: I'd like the sound to play at regular intervals over the course of the timer (in addition to at the end). For example, in a ten minute timer, the sound might play every 60 seconds.
Things I've tried:
if
statement inside the onTick
method to check when millisUntilFinished
is equal to a certain value (a multiple of 60 seconds, for example) and then running the method. This seems like the most straightforward solution, but I've found that the method is not triggered consistently (perhaps millisUntilFinished
is skipping over the value I'm checking it against?). CountDownTimers
and repeating with a for
loop. The problem with this is that the code quickly becomes overly complicated and my intuition tells me that I shouldn't be running timers within timers. Question: How can I run a method at regular intervals over the course of a CountDownTimer?
Instead of using a countdown timer you can simply use a post delayed Handler and thread.At the end of the method post the handler with specified time interval as below code
Runnable myThread = new Runnable() {
@Override
public void run() {
//call the method here
myHandler.postDelayed(myThread, 1000);//calls thread after 60 seconds
}
};
myHandler.post(myThread);//calls the thread for the first time
After thinking on this for a while I came up with a solution that satisfies my chief requirement of simplicity. Here's how to employ it:
Declare two class-level variables
private long startTime = 60000; // Set this equal to the length of the CountDownTimer
private long interval = 10000; // This will make the method run every 10 seconds
Declare a method to run on an interval inside the CountDownTimer
private void runOnInterval(long millisUntilFinished) {
if (millisUntilFinished < startTime) {
playSound();
startTime -= interval;
}
}
And then call the method in the onTick
method of the CountDownTimer
// ...
@Override
public void onTick(long millisUntilFinished) {
runOnInterval(millisUntilFinished);
}
// ...
And here's how it works: The onTick
method of the CountDownTimer
passes millisUntilFinished
each time it ticks. Then runOnInterval()
checks to see if that value is less than startTime
. If it is, it runs the code inside the if
statement (in my case, playSound()
) and then decrements startTime
by the value of interval
. Once millisUntilFinished
is lower than startTime
again, the process starts all over again.
The above code is simpler than employing another CountDownTimer
or a Handler
and a Runnable
. It also automatically works with any sort of functionality one might have added to the activity to handle CountDownTimer
pauses and resets.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.