I have problem with Countdown Timer. When I press button the Timer starts and after clossing app and waiting for a while the Timer stops. So the main idea what I want to do is to let app be awake in background process until the Timer Finish. I dont know the code or in which direction I should go. Please help me. Thanks a lot!
//paste the following code inside your button method
// mind you the example giving here is countdown for 60 seconds
int yoursecondsLeft = 0;
new CountDownTimer(60000, 100) {
public void onTick(long milliseconds) {
/////////////////////////////////////////////////////////////
////////////////////////This is the code that convert to real system time so that yo will have your exact seconds//////////////////////////////
if (Math.round((float)milliseconds / 1000.0f) != yoursecondsLeft)
{
syoursecondsLeft = Math.round((float)milliseconds / 1000.0f);
}
//////////////////////////////////////////////////////////////////////////////
Log.i("test","ms="+milliseconds+" till finished="+yoursecondsLeft );
// You can print the count down value to your texview here: e.g tv.setText(yoursecondsLeft);
}
public void onFinish() {
/*Close your application here: you can now call this method here: finish(); to end your application */
Log.i("finish","Countdown completed");
}
}.start();
Related
I'm trying to start, end, and reset+restart a timer using two different if statements in the onDataChange method. The thing I can't get to work is getting the timer to restart if the first if statement is triggered again after the second one stops the timer. After the class declaration at the top, I have
Timer firstTestTimer = new Timer();
TimerTask increaseByTwo = new TimerTask() {
#Override
public void run() {
incrementalCount = incrementalCount + 2;
System.out.println(incrementalCount);
}
};
and in the onCreate method I have a Firebase reference with a ValueEventListener with the following code:
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String Motion1 = dataSnapshot.child("Enter").getValue().toString();
if(Motion1.equals("YES")){
incrementalCount = 0;
firstTestTimer.schedule(increaseByTwo, 2000,2000);
}
if(Motion1.equals("STOP")){
firstTestTimer.cancel();
firstTestTimer.purge();
System.out.println("Total seconds elapsed since sensor showed YES: "+incrementalCount);
if(incrementalCount > 11){
System.out.println("The difference is greater than 11 seconds");
}
}
}
As of right now, when the Firebase value initially changes to "YES", the timer starts and every two seconds it increases incrementalCount by 2. When the Firebase value changes to "STOP", the timer shows the correct amount of seconds that have passed. Here's the problem: When the Firebase value changes to "YES" again, the app crashes and gives me some variation of java.lang.IllegalStateException: Task already scheduled or cancelled
Is it possible to reset and restart the timer with a fresh count whenever the Firebase value changes to "YES"? Thank you!
As #ThomasKläger pointed out, you can't use a TimerTask again. The docs point out that:
A timer task is not reusable. Once a task has been scheduled for execution on a Timer or canceled, subsequent attempts to schedule it for execution will throw IllegalStateException.
It is like a plastic cup or spoon, built to be used only once. So every time you have to increment your timer, here's what you can do:
Leave the timer as it is and define the timer task object again:
if (Motion1.equals("YES")){
incrementalCount = 0;
//Define it again, I think it is a waste of time to check whether the task exists or not.
increaseByTwo = new TimerTask() {
#Override
public void run() {
incrementalCount = incrementalCount + 2;
System.out.println(incrementalCount);
}
};
firstTestTimer.schedule(increaseByTwo, 2000,2000);
}
The rest of the code is the same. This should work.
The documentation for TimerTask is here: TimerTask JDK 11
For some reason even though I am using the exact code example from oracle's website for the Swing Timer it is not waiting for 1 second. It just skips to the JOptionPane that says "Your score was etc etc".
Here is my source code for a school project. Why is this not working and not waiting for 1 second before running the rest of the code?
//Check to see if user has enetered anything
if(!answered)
{
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...Perform a task...
}
};
new Timer(delay, taskPerformer).start();
afk = true;
incorrect += 1;
answered = true; //This breakes it out of the loop
}
A timer is used to run a callback after a specific amount of time. If you simply want to delay, you can either move the code to be run after the delay into the taskPerformer action listener.
Thread.sleep(1000) is not ideal here, because it will cause the UI to completely freeze as you will make the UI thread sleep.
This question already has an answer here:
my timer in eclipse did not work properly
(1 answer)
Closed 8 years ago.
guys I am new to the eclipse, I am practicing the timer in eclipse, can I have some help for my codes?
The code below is like if I clicked the trigger button while it is counting, it will trigger another counting without stop the previous counting.
I have tried chancel the button or reactive it after the down counting, still i want to know how to make the same trigger button acquire the restart counting function. Can u help me by directly embed to my code please? I know i am too new to eclipse, java even eng, everything, i would need your explanation if it is not going to take your take too much.
Button countDownButton2 = (Button) findViewById(R.id.countDown1);
countDownButton2.setOnClickListener(new View.OnClickListener() {
public void onClick(View view){
CountDownTimer timer2 = new CountDownTimer(3000,1000){
#Override
public void onFinish() {
mTimeLabel1.setText("Times Up baby!");
}
#Override
public void onTick(long millisUntilFinished) {
int seconds = (int) (millisUntilFinished / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
mTimeLabel1.setText("" + minutes + ":"
+ String.format("%02d", seconds));
}
}.start();
}
});
Your current solution is creating an new countdowntimer but not stopping the old one. Therefore if you click the button again you have 2 countdown timers. When you say "new CountDowntimer", that is when you create it. Therefore, before you create a new one, make sure to stop the previous one.
Button countDownButton2 = (Button) findViewById(R.id.countDown1);
countDownButton2.setOnClickListener(new View.OnClickListener() {
CountDownTimer timer2;
public void onClick(View view){
if(timer2!=null){
timer2.cancel();
}
timer2 = new CountDownTimer(3000,1000){
#Override
public void onFinish() {
mTimeLabel1.setText("Times Up baby!");
}
#Override
public void onTick(long millisUntilFinished) {
int seconds = (int) (millisUntilFinished / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
mTimeLabel1.setText("" + minutes + ":"
+ String.format("%02d", seconds));
}
}.start();
}
});
Explanation
Previously, each time you clicked the button you had a new CountDownTimer. Each countdown timer was changing the value of the label mTimeLabel1. The new timer is created because inside your on click lister, you were doing this:
CountdownTimer2 timer2 = new CountDownTimer(3000,1000)
This means, create a new Timer, and keep a reference to it called timer2. After the onClick method is finished, the timer keeps running. However, when you click again you create a new timer and a new reference to the old timer is lost. The reference is not to the old one but to the new one.
So, instead we make sure that the click listener has only one timer. To do this we move the reference to it outside of the onClick method so that we can keep the reference to the timer. We can then make sure that we check this timer to cancel it before starting another one. However, if it is the first time that you have clicked on the button then the timer will be null, because "new CountdownTimer" hasn't yet been called. So, we check that it is not null (it's not the first button press), and if it is not then cancel the old one before creating a new one. If it is the first button press, we don't want to call cancel because there is no timer to cancel.
I have an app with multiple timers; when I start one, I can see it counting down in Logcat in Eclipse.
When I hit the Back button, onStop() is called in the app but the timer continues to countdown in logcat (the onTick() is continuing to tick away).
What I would like is when onResume() is called, I want to get that timer which is still counting down and continue it. Is this possible?
Here are my buttons that start the countdown:
//Button1 Timer
final CountDown button1 = new CountDown(420000,1000,bButton1);
bButton1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
button1.start();
long currentTime = System.currentTimeMillis();
//Set start time for calculating time elapsed if needed
saveTime("START_TIME_BUTTON1", currentTime);
}
});
//Button2 Timer
final CountDown button2 = new CountDown(360000,1000,bButton2);
bButton2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
button2.start();
long currentTime = System.currentTimeMillis();
//Set start time for calculating time elapsed if needed
saveTime("START_TIME", currentTime);
}
});
My onResume() looks like this:
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
//Reset the timers on appropriate buttons if there was something running
//If nothing was running or timer finished - have button in default state
//See if there was a button1 timer running - if not, it will be 0
SharedPreferences start = PreferenceManager.getDefaultSharedPreferences(this);
long startTime = start.getLong("START_TIME_BUTTON1", 0);
long timeElapsed = (System.currentTimeMillis()-startTime);
long timeRemaining = (420000 - timeElapsed);
if (timeRemaining == 0) {
} else if (timeRemaining > 0) {
final CountDown button1Timer = new CountDown(timeRemaining,1000,bButton1);
button1Timer.start();
long currentTime = System.currentTimeMillis();
saveTime("START_TIME", currentTime);
} else {
}
}
This actually works — the onResume() starts another timer right where the first one would be, and the text displays the appropriate number and continues counting down with the onTick() method. But now logcat shows 2 timers counting down instead of just one!
Ultimately I wouldn't want to start another timer, I just want to pick up the first timer I started where it is currently in the countdown at and have the onTick() display appropriately. Is there a way to do that? Would services be what I'm looking for? Is it already a service since it continues to tick down in the background?
I'm a little confused on what would be best practice to get this done.
onTick() will continue being called until either the time remaining reaches 0 or you call cancel() on the CountDownTimer.
So in your onStop() method you will need to call cancel() on the timer you want to stop receiving onTick() notifications.
Android's implementation of CountDownTimer uses a Handler to perform timing by queuing a Message to be sent to the Handler after each tick. Unfortunately there is no way to pause the CountDownTimer, so I believe you will need to create a new Timer with the appropriate values like you're doing currently.
When you're calculating the timeElapsed, you shouldn't use System.currentTimeMillis() because it can be changed at any time, instead you should use SystemClock.elapsedRealtime(). System.currentTimeMillis() is the timer used for the wall clock (time and date) and so can change unpredictably, see the Android documentation.
I am working on an app, which gets a sort of restart with an event. On the first run, the timer works perfect (1sec = 1 increment). but, on next run (1sec = 2 increment) on third run (1sec = 4 increment) and so on...
I think there is something wrong with the new TimerTask object being created. but, dunno how to handle it. any suggestion or alternate ?
CODE SNIPPET:
Timer t = new Timer();
void timerMethod()
{
t.schedule(new TimerTask() {
public void run() {
timerInt++;
//TODO bug in timer in consecutive runs. To confirm, see log
Log.d("timer", "timer " + timerInt);
/* runOnUiThread(new Runnable() {
#Override
public void run() {
timerDisplayPanel.setText( timerInt + " Sec");
}
});*/
}
}, 1000, 1000);
}
It sounds like you're calling timerMethod() multiple times.
When you've called it three times, you've got three timer tasks scheduled - so they'll all fire each second, and all increment timerInt. You either need to not call it multiple times, or cancel the existing timer tasks before adding more.
If that's not the case, please provide a short but complete program to show what's happening. The context is fairly vague at the moment.
The snippet you provided is working properly
1 sec 1 increment
2 sec 2 increment
3 sec 3 increment
etc
So probably the problem is somewhere else in your code.