public void counter(){
new CountDownTimer(20000, 1000){
#Override
public void onTick(long millisUntilFinished) {
progressBar.setProgress(Integer.parseInt(String.valueOf(millisUntilFinished/1000)));
}
#Override
public void onFinish() {
gameOver();
}
}.start();
}
I am trying to write a game in which player gets 20 seconds to play. A timer starts at start of the game and if timer reaches 0, player looses. If player presses button with correct answer, i want time to increase by 3 seconds. But I don't know how to add time in the count down timer whenever player hits correct answer. I tried everything but couldn't find a way. If there is another method to achieve this, please tell me. Thank you
Change your code like this:
private int globalCount = 0; // Initialize this in Global scope of class.
public void counter(int timeCount){
globalCount = 0;
new CountDownTimer(timeCount, 1000){
#Override
public void onTick(long millisUntilFinished) {
progressBar.setProgress(Integer.parseInt(String.valueOf(millisUntilFinished/1000)));
}
#Override
public void onFinish() {
if (globalCount == 0) {
gameOver();
} else {
conter(globalCount);
}
}
}.start();
}
One last thing you have to do is:
globalCount += 3000;
every time when user pressed the right answer button. Hope this will help!
In Android normal countdown timer is used for decrease order. so you can use logic using normal if-else condition.
if (sec==59){
sec = 0;
min = min+1;
String text = String.format(Locale.getDefault(),"%02d min: %02d sec",min,sec);
editText.setText(text);
}else {
sec = sec+1;
String text = String.format(Locale.getDefault(),"%02d min: %02d sec",min,sec);
editText.setText(text);
}
}
You can get complete code using this blog
This question already has answers here:
How to run a thread repeatedly after some interval
(3 answers)
Closed 4 years ago.
I am developing an Android App in which I need to run a piece of code every minute, when I say every minute I mean it should be synced with the device's time so every time the device time changes by one minute my code is executed.
So far I tried this but it is not working:
runnable=new Runnable(){
#Override
public void run(){
long now=SystemClock.uptimeMillis();
long next=now+(60000 - now % 60000);
handler.postAtTime(this, next);
}
};
runnable.run();
There are many other ways to do this:
1) Timer.scheduleAtFixedRate()
2) Thread.sleep(interval)
3) Alarm Manager
In your way it will look like this:
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
try{
//do your code here
}
catch (Exception e) {
// TODO: handle exception
}
finally{
//also call the same runnable to call it at regular interval
handler.postDelayed(this, "*interval");
}
}
};
handler.postDelayed(runnable, "*interval");
you can see this answer for details
You can use this code:
Thread thread = new Thread(new Runnable()
{
int lastMinute;
int currentMinute;
#Override
public void run()
{
lastMinute = currentMinute;
while (true)
{
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
currentMinute = calendar.get(Calendar.MINUTE);
if (currentMinute != lastMinute){
lastMinute = currentMinute;
Log.v("LOG", "your code here");
}
}
}
});
thread.run();
one can use handle and can give input as milliseconds and we can call the code for every minute and should not use any infinite loops while using two different layouts
final Handler handler = new Handler();
Runnable run = new Runnable() {
#Override
public void run() {
handler.postDelayed(this, 60000);
}
};
handler.post(run);
You can use handler if you want to initiate something every X seconds. Handler is good because you don't need extra thread to keep tracking when firing the event. Here is a Code:
private final static int INTERVAL = 1000 * 60 * 1; //1 minutes
Handler mHandler = new Handler();
Runnable mHandlerTask = new Runnable()
{
#Override
public void run() {
doSomething();
mHandler.postDelayed(mHandlerTask, INTERVAL);
}
};
void startRepeatingTask()
{
mHandlerTask.run();
}
void stopRepeatingTask()
{
mHandler.removeCallbacks(mHandlerTask);
}
The modern method
new Handler().postDelayed(() -> {
}, 30000);
I'm just trying to change the color of my drawn circle with a timer. I have implemented following code into my "onCreate" method:
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
Drawing.switchColor();
}
});
}
},
1000,
1000);
The method switchColor() does the following action:
public static void switchColor() {
Random r = new Random(30);
int random = r.nextInt();
if(random < 10) {
p.setColor(Color.GREEN);
}
else if(random >10 && random < 20) {
p.setColor(Color.BLUE);
}
else {
p.setColor(Color.RED);
}
}
When I run this, the color stays at it's default.
Does anyone know whether I have to use a handler within or a different timer model?
Thanks in advance!
I now found a suitable solution:
//-------------------Part 1 of AddCircleTimer------------------------
//Declare the timerAddCircle
timerAddCircle = new Timer();
timerAddCircle.schedule(new TimerTask() {
#Override
public void run() {
TimerMethodAddCircle();
}
}, 1000, 1000);
//-------------------Part 2 of AddCircleTimer------------------------
private void TimerMethodAddCircle()
{
//This method is called directly by the timer and runs in the same thread as the timer.
//We call the method that will work with the UI through the runOnUiThread method.
this.runOnUiThread(Timer_Add);
}
private Runnable Timer_Add = new Runnable() {
public void run() {
//This method runs in the same thread as the UI.
//Do something to the UI thread here
Drawing.addCircle();
d.invalidate();
}
};
//-------------------END Part 2 of AddCircleTimer------------------------
This works very fine and I can use it for even more timers and different methods!
Thanks to all!
Your t.start() is missing, either in onCreate, onStart, or onResume, depending on when you want to start your timer.
I want an app which changes background color when pressing a button. After 500 ms, I want to change background color to black for 2000ms. And then repeat whole process again, until user terminates that.
I have following code but its not working as I think it should.
private void set() {
rl.setBackgroundColor(Color.WHITE);
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
rl.setBackgroundColor(Color.BLACK);
set(); // can I do that?
}
});
}
}, 500);
}
Can someone point me to right direction how can I do that? So I want:
Execute some code
After X time passed by , I want to execute another code and it should stay that way for X amount of time
Repeat process until user cancels that.
Something like this should work I think
Handler handler = new Handler();
Runnable turnBlack = new Runnable(){
#Override
public void run() {
myView.setBackgroundColor(Color.BLACK);
goWhite();
}};
Runnable turnWhite = new Runnable(){
#Override
public void run() {
myView.setBackgroundColor(Color.White);
goBlack();
}};
public void goBlack() {
handler.postDelayed(turnBlack, 500);
}
public void goWhite() {
handler.postDelayed(turnWhite, 2000);
}
There is much easier way to do this using AnimationDrawable:
AnimationDrawable drawable = new AnimationDrawable();
ColorDrawable color1 = new ColorDrawable(Color.YELLOW);
ColorDrawable color2 = new ColorDrawable(Color.BLACK);
// First color yellow for 500 ms
drawable.addFrame(color1, 500);
// Second color black for 2000 ms
drawable.addFrame(color2, 2000);
// Set if animation should loop. In this case yes it will
drawable.setOneShot(false);
Button btn = (Button)findViewById(R.id.button1);
btn.setBackground(drawable);
findViewById(R.id.buttonLan).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Start animation
((AnimationDrawable)v.getBackground()).start();
}
});
I have one simple question regarding Java TimerTask. How do I pause/resume two TimerTask tasks based on a certain condition? For example I have two timers that run between each other. When a certain condition has been met inside the task of first timer, the first timer stops and starts the second timer, and the same thing happens when a certain condition has been met inside the task of second timer. The class below shows exactly what I mean:
public class TimerTest {
Timer timer1;
Timer timer2;
volatile boolean a = false;
public TimerTest() {
timer1 = new Timer();
timer2 = new Timer();
}
public void runStart() {
timer1.scheduleAtFixedRate(new Task1(), 0, 1000);
}
class Task1 extends TimerTask {
public void run() {
System.out.println("Checking a");
a = SomeClass.getSomeStaticValue();
if (a) {
// Pause/stop timer1, start/resume timer2 for 5 seconds
timer2.schedule(new Task2(), 5000);
}
}
}
class Task2 extends TimerTask{
public void run() {
System.out.println("Checking a");
a = SomeClass.getSomeStaticValue();
if (!a) {
// Pause/stop timer2, back to timer1
timer1.scheduleAtFixedRate(new Task1(), 0, 1000);
}
// Do something...
}
}
public static void main(String args[]) {
TimerTest tt = new TimerTest();
tt.runStart();
}
}
So my question is, how do I pause timer1 while running timer2 and vice versa while timer2 is running? Performance and timing is my main concern as this needs to be implemented inside another running thread. By the way I am trying to implement these concurrent timers on Android.
Thanks for your help!
From TimerTask.cancel():
Note that calling this method from
within the run method of a repeating
timer task absolutely guarantees that
the timer task will not run again.
So once cancelled, it won't ever run again. You'd be better off instead using the more modern ScheduledExecutorService (from Java 5+).
Edit: The basic construct is:
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(runnable, 0, 1000, TimeUnit.MILLISECONDS);
but looking into it there's no way of cancelling that task once its started without shutting down the service, which is a bit odd.
TimerTask might be easier in this case but you'll need to create a new instance when you start one up. It can't be reused.
Alternatively you could encapsulate each task as a separate transient service:
final ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
Runnable task1 = new Runnable() {
public void run() {
a++;
if (a == 3) {
exec.shutdown();
exec = Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(task2, 0, 1000, TimeUnit.MILLISECONDS)
}
}
};
exec.scheduleAtFixedRate(task1, 0, 1000, TimeUnit.MILLISECONDS);
easiest solution i found: just add a boolean in the run code in the timer task, like so:
timer.schedule( new TimerTask() {
public void run() {
if(!paused){
//do your thing
}
}
}, 0, 1000 );
If you have already canceled one timer, you can't re-start it, you'll have to create a new one.
See this answer, it contains a video and the source code how I did something similar.
Basically there are two method: pause and resume
In pause:
public void pause() {
this.timer.cancel();
}
In resume:
public void resume() {
this.timer = new Timer();
this.timer.schedule( aTask, 0, 1000 );
}
That makes the perception of pause/resume.
If your timers perform different actions based on the state of the application you may consider use the StatePattern
Fist define a abstract state:
abstract class TaskState {
public void run();
public TaskState next();
}
And provide as many states as you like. The key is that one state leads you to another.
class InitialState extends TaskState {
public void run() {
System.out.println( "starting...");
}
public TaskState next() {
return new FinalState();
}
}
class FinalState extends TaskState {
public void run() {
System.out.println("Finishing...");
}
public TaskState next(){
return new InitialState();
}
}
And then you change the state in your timer.
Timer timer = new Timer();
TaskState state = new InitialState();
timer.schedule( new TimerTask() {
public void run() {
this.state.run();
if( shouldChangeState() ) {
this.state = this.state.next();
}
}
}, 0, 1000 );
Finally, if what you need is to perform the same thing, but at different rates, you may consider using the TimingFramework. It is a bit more complex but let's you do cool animations, by allowing the painting of certain component take place at different rates ( instead of being linear )
In my opinion, this is somewhat misguided. If your code needs time guarantees, you can't use Timer anyway, nor would you want to. "This class does not offer real-time guarantees: it schedules tasks using the Object.wait(long) method."
The answer, IMHO, is that you don't want to pause and restart your timers. You just want to suppress their run methods from doing their business. And that's easy: you just wrap them in an if statement. The switch is on, they run, the switch is off, they miss that cycle.
Edit: The question has shifted substantially from what it was originally, but I'll leave this answer in case it helps anyone. My point is: if you don't care when your event fires in the N millisecond span (just that it doesn't EXCEED once every N milliseconds), you can just use conditionals on the run methods. This is, in fact, a very common case, especially when N is less than 1 second.
Reviewing your source code, here are the changes ( which pretty much validate my previous answer )
In task1:
// Stop timer1 and start timer2
timer1.cancel();
timer2 = new Timer(); // <-- just insert this line
timer2.scheduleAtFixedRate(new Task2(), 0, 1000);
and in task2:
// Stop timer2 and start timer1
timer2.cancel();
timer1 = new Timer(); // <-- just insert this other
timer1.scheduleAtFixedRate(new Task1(), 0, 1000);
It runs on my machine:
Android won't reuse a TimerTask that has already been scheduled once. So it's necessary to reinstantiate both the Timer and TimerTask, for example like this in a Fragment:
private Timer timer;
private TimerTask timerTask;
public void onResume ()
{
super.onResume();
timer = new Timer();
timerTask = new MyTimerTask();
timer.schedule(timerTask, 0, 1000);
}
public void onPause ()
{
super.onPause();
timer.cancel(); // Renders Timer unusable for further schedule() calls.
}
I am able to stop a timer and a task using following code:
if(null != timer)
{
timer.cancel();
Log.i(LOG_TAG,"Number of cancelled tasks purged: " + timer.purge());
timer = null;
}
if(task != null)
{
Log.i(LOG_TAG,"Tracking cancellation status: " + task.cancel());
task = null;
}
Timer timer1;
private boolean videoCompleteCDR=false;
private boolean isVideoPlaying=false;
int videoTime=0;
private int DEFAULT_VIDEO_PLAY_TIME = 30;
#Override
public View onCreate(){
isVideoPlaying = true; //when server response is successfully
}
#Override
public void onPause() {
super.onPause();
if(isVideoPlaying ) {
if(this.timer1 !=null) {
this.timer1.cancel();
}
}
}
#Override
public void onResume() {
super.onResume();
if(isVideoPlaying && !videoCompleteCDR) {
callTimerTask();
}
}
#Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (!hidden) {
printLog( "GameFragment visible ");
if(isVideoPlaying && !videoCompleteCDR) {
callTimerTask();
}
} else {
printLog("GameFragment in visible ");
if(isVideoPlaying) {
if(this.timer1 !=null) {
this.timer1.cancel();
}
}
}
}
private void callTimerTask() {
// TODO Timer for auto sliding
printLog( "callTimerTask Start" );
timer1 = new Timer();
timer1.schedule(new TimerTask() {
#Override
public void run() {
if (getActivity() != null) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
if (getActivity() == null) {
return;
}
videoTime++;
if(DEFAULT_VIDEO_PLAY_TIME ==videoTime){
videoCompleteCDR=true;
Log.e("KeshavTimer", "callTimerTask videoCompleteCDR called.... " +videoTime);
destroyTimer();
}
Log.e("KeshavTimer", "callTimerTask videoTime " +videoTime);
}
});
} else {
printLog("callTimerTask getActivity is null ");
}
}
}, 1000, 1000);
// TODO 300, 2000;
}
private void destroyTimer(){
this.timer1.cancel();
}