CountdownTimer Add Time and Cancel in OnTick - android

I have a countdown timer and I want to add 10 seconds to it whenever my isAddTime method is true. I have successfully added it but whenever the time is added, it still finishes on the current time.
I am cancelling it in OnTick Method i tried to cancel it in other class and i successfully cancel it but i cant resume the timer.. since to cancel it in another class it will be static.
Here's my code:
timerHolder = new CountDownTimer(30000, 1000) {
#Override
public void onFinish() {
Class.isAddTime = false;
Intent i = new Intent(getBaseContext(), OtherClass.class);
startActivity(i);
}
#Override
public void onTick(long millisUntilFinished) {
timeLeft = millisUntilFinished;
if(Class.isAddTime()){
timerHolder.cancel();
AddTime();
Class.isAddTime = false;
}
timer.setText("Time left: " + String.valueOf(timeLeft / 1000));
}
}.start();
And here is the AddTime():
private void AddTime(){
timerHolder = new CountDownTimer(timeLeft + 10000, 1000) {
#Override
public void onFinish() {
Class.isAddTime = false;
Intent i = new Intent(getBaseContext(), OtherClass.class);
startActivity(i);
}
#Override
public void onTick(long millisUntilFinished) {
timeLeft += 10000;
timeLeft = millisUntilFinished;
if(Class.isAddTime()){
timerHolder.cancel();
AddTime();
Class.isAddTime = false;
}
timer.setText("Time left: " + String.valueOf(timeLeft / 1000));
}
}.start();
I was wondering why it still continue the current time even if i had it cancelled? is there other way to call cancel? is there more clean solution on how i can add time to the countdown timer?

Some people solved this problem by using custom timer. With this timer you'll be able to cancel the time inside onTick() method.
https://gist.github.com/Gautier/737759
Here is the code on Github. Hope it helps.
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package alt.android.os;
import android.util.Log;
import android.os.Handler;
import android.os.SystemClock;
import android.os.Message;
/**
* Schedule a countdown until a time in the future, with
* regular notifications on intervals along the way.
*
* Example of showing a 30 second countdown in a text field:
*
* <pre class="prettyprint">
* new CountdownTimer(30000, 1000) {
*
* public void onTick(long millisUntilFinished) {
* mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
* }
*
* public void onFinish() {
* mTextField.setText("done!");
* }
* }.start();
* </pre>
*
* The calls to {#link #onTick(long)} are synchronized to this object so that
* one call to {#link #onTick(long)} won't ever occur before the previous
* callback is complete. This is only relevant when the implementation of
* {#link #onTick(long)} takes an amount of time to execute that is significant
* compared to the countdown interval.
*/
public abstract class CountDownTimer {
/**
* Millis since epoch when alarm should stop.
*/
private final long mMillisInFuture;
/**
* The interval in millis that the user receives callbacks
*/
private final long mCountdownInterval;
private long mStopTimeInFuture;
private boolean mCancelled = false;
/**
* #param millisInFuture The number of millis in the future from the call
* to {#link #start()} until the countdown is done and {#link #onFinish()}
* is called.
* #param countDownInterval The interval along the way to receive
* {#link #onTick(long)} callbacks.
*/
public CountDownTimer(long millisInFuture, long countDownInterval) {
mMillisInFuture = millisInFuture;
mCountdownInterval = countDownInterval;
}
/**
* Cancel the countdown.
*
* Do not call it from inside CountDownTimer threads
*/
public final void cancel() {
mHandler.removeMessages(MSG);
mCancelled = true;
}
/**
* Start the countdown.
*/
public synchronized final CountDownTimer start() {
if (mMillisInFuture <= 0) {
onFinish();
return this;
}
mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
mHandler.sendMessage(mHandler.obtainMessage(MSG));
mCancelled = false;
return this;
}
/**
* Callback fired on regular interval.
* #param millisUntilFinished The amount of time until finished.
*/
public abstract void onTick(long millisUntilFinished);
/**
* Callback fired when the time is up.
*/
public abstract void onFinish();
private static final int MSG = 1;
// handles counting down
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
synchronized (CountDownTimer.this) {
final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
if (millisLeft <= 0) {
onFinish();
} else if (millisLeft < mCountdownInterval) {
// no tick, just delay until done
sendMessageDelayed(obtainMessage(MSG), millisLeft);
} else {
long lastTickStart = SystemClock.elapsedRealtime();
onTick(millisLeft);
// take into account user's onTick taking time to execute
long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();
// special case: user's onTick took more than interval to
// complete, skip to next interval
while (delay < 0) delay += mCountdownInterval;
if (!mCancelled) {
sendMessageDelayed(obtainMessage(MSG), delay);
}
}
}
}
};
}

make timerHolder object null after canceling it.
if(Class.isAddTime()){
timerHolder.cancel();
timerHolder=null;
AddTime();
Class.isAddTime = false;
}

Related

Working example of countdown timer with smooth progress bar

I've seen many similar questions but I can't find any code that actually works so please modify this example so the progress bar moves smoothly.
activity_main.xml
I've seen some answers that increase the max and reduce the time interval but I don't see it working properly. There are other answers that use the animator class and work fine but then I don't know how to update the numbers.
package com.example.arturo_2.countdowntimertutorial;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.os.CountDownTimer;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private long timeCountInMilliSeconds = 1 * 60 * 1000;
private ProgressBar progressBarCircle;
private EditText editTextMinute;
private TextView textViewTime;
private Button buttonDecrease;
private Button buttonIncrease;
private Button buttonStop;
private CountDownTimer countDownTimer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// method call to initialize the views
initViews();
// method call to initialize the listeners
initListeners();
start();
}
/**
* method to initialize the views
*/
private void initViews() {
progressBarCircle = (ProgressBar) findViewById(R.id.progressBarCircle);
editTextMinute = (EditText) findViewById(R.id.editTextMinute);
textViewTime = (TextView) findViewById(R.id.textViewTime);
buttonDecrease = (Button) findViewById(R.id.buttonDecrease);
buttonIncrease = (Button) findViewById(R.id.buttonIncrease);
buttonStop = (Button) findViewById(R.id.fab_stop);
}
/**
* method to initialize the click listeners
*/
private void initListeners() {
buttonDecrease.setOnClickListener(this);
buttonIncrease.setOnClickListener(this);
buttonStop.setOnClickListener(this);
}
/**
* method to increase timer value
*/
private void increase() {
timeCountInMilliSeconds += 15 * 1000;
setProgressBarValues();
}
/**
* method to decrease timer value
*/
private void decrease() {
timeCountInMilliSeconds -= 15 * 1000;
setProgressBarValues();
}
/**
* method to cancel count down timer
*/
private void stop() {
countDownTimer.cancel();
}
/**
* implemented method to listen clicks
*
* #param view
*/
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.buttonDecrease:
decrease();
break;
case R.id.buttonIncrease:
increase();
break;
case R.id.fab_stop:
stop();
break;
}
}
/**
* method to initialize the values for count down timer
*/
private void setTimerValues() {
int time = 0;
if (!editTextMinute.getText().toString().isEmpty()) {
// fetching value from edit text and type cast to integer
time = Integer.parseInt(editTextMinute.getText().toString().trim());
}
// assigning values after converting to milliseconds
timeCountInMilliSeconds = time * 60 * 1000;
setProgressBarValues();
}
/**
* method to set circular progress bar values
*/
private void setProgressBarValues() {
progressBarCircle.setMax((int) timeCountInMilliSeconds / 1000);
progressBarCircle.setProgress((int) timeCountInMilliSeconds / 1000);
}
/**
* method to start count down timer
*/
private void start() {
setTimerValues();
startCountDownTimer();
}
/**
* method to start count down timer
*/
private void startCountDownTimer() {
countDownTimer = new CountDownTimer(timeCountInMilliSeconds, 1000) {
#Override
public void onTick(long millisUntilFinished) {
textViewTime.setText(hmsTimeFormatter(millisUntilFinished));
progressBarCircle.setProgress((int) (millisUntilFinished / 1000));
}
#Override
public void onFinish() {
textViewTime.setText(hmsTimeFormatter(timeCountInMilliSeconds));
setProgressBarValues(); // call to initialize the progress bar values
}
}.start();
countDownTimer.start();
}
/**
* method to convert millisecond to time format
*
* #param milliSeconds
* #return mm:ss time formatted string
*/
private String hmsTimeFormatter(long milliSeconds) {
String hms = String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(milliSeconds),
TimeUnit.MILLISECONDS.toSeconds(milliSeconds) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(milliSeconds)));
return hms;
}
}
MainActivity.java, activity_main.xml
private void setProgressBarValues() {
progressBarCircle.setMax((int) timeCountInMilliSeconds / 50);
progressBarCircle.setProgress((int) timeCountInMilliSeconds / 1000);
}
private void startCountDownTimer() {
countDownTimer = new CountDownTimer(timeCountInMilliSeconds, 50) {
#Override
public void onTick(long millisUntilFinished) {
textViewTime.setText(hmsTimeFormatter(millisUntilFinished));
progressBarCircle.setProgress((int) (millisUntilFinished / 50));
}
#Override
public void onFinish() {
textViewTime.setText(hmsTimeFormatter(timeCountInMilliSeconds));
setProgressBarValues(); // call to initialize the progress bar values
}
}.start();
countDownTimer.start();
}

Pause/Resume CountDownTimer Android

Is it possible to pause a CountDownTimer in Android? I have been looking for good solutions but I just find some ways to do this that I really don't like. As just save the left time in a variable and initialize a new CountDownTimer with that values.
That kind of solutions work but they didn't look so good because I´m using a circle Progress bar and a Textview together with my countdownTimer. Was really ugly try to look this two look good with the CountDown without be able to really "pause" it.
Here is my code for initialize the CountDownTimer with a ProgressBar and a TextView.
public void initProgress() {
if (mCountdownProgressBar == null)
mCountdownProgressBar = (CircleProgressBar) findViewById(R.id.progressBar);
mCountDownTime = 30000; //Insert your desire time in Milliseconds here
mCountdownProgressBar.setMaxProgress((int)TimeUnit.MILLISECONDS.toSeconds(mCountDownTime));
mCountDownTimer = new CustomCountDownTimer(mCountDownTime, 1000) {
#Override
public void onTick(long millisUntilFinished) {
Log.v("Log_tag", "Tick of Progress" + TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished));
mCountdownProgressBar.setmProgress(TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished));
mTimer.setText(Util.getTimeForTimer(millisUntilFinished, Util.TIME_FORMAT));
}
#Override
public void onFinish() {
mCountdownProgressBar.setmProgress(0);
mTimer.setText(Util.getTimeForTimer(0, Util.TIME_FORMAT));
}
};
mCountDownTimer.start();
}
With this code you will be able to set a progressBar and a TextView together with your CountDownTimer. To be able to pause and resume it pretty easy I will post next a Custom Class for CountDownTimer.
Here is the solution!
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
public abstract class CustomCountDownTimer {
private final String TAG = "CustomCountDownTimer";
/**
* Millis since epoch when alarm should stop.
*/
private final long mMillisInFuture;
/**
* The interval in millis that the user receives callbacks
*/
private final long mCountdownInterval;
/**
* The time in millis when the timer was paused
*/
private long mTimePaused;
/**
* The final time when the timer must to stop (actual hour + countdown in millis)
*/
private long mStopTimeInFuture;
/**
* boolean representing if the timer was cancelled
*/
private boolean mCancelled = false;
/**
* boolean representing if the timer is paused
*/
private boolean mPause = false;
/**
* #param millisInFuture The number of millis in the future from the call
* to {#link #start()} until the countdown is done and {#link #onFinish()}
* is called.
* #param countDownInterval The interval along the way to receive
* {#link #onTick(long)} callbacks.
*/
public CustomCountDownTimer(long millisInFuture, long countDownInterval) {
mMillisInFuture = millisInFuture;
mCountdownInterval = countDownInterval;
}
/**
* Cancel the countdown.
*/
public synchronized final void cancel() {
mCancelled = true;
mHandler.removeMessages(MSG);
}
/**
* Pause the countdown.
*/
public synchronized final void pause() {
cancel();
//Save the time and hour to resume the timer correctly later.
mTimePaused = SystemClock.elapsedRealtime();
mPause = true;
}
/**
* Resume the countdown.
*/
public synchronized final void resume() {
//Booleans back to false value
mPause = false;
mCancelled = false;
//We set the time to a new one because the elapsedTime as change
mStopTimeInFuture = mStopTimeInFuture + (SystemClock.elapsedRealtime() - mTimePaused);
Log.d(TAG, "mStopTimeInFuture: " + mStopTimeInFuture);
mHandler.sendMessage(mHandler.obtainMessage(MSG));
}
/**
* Start the countdown.
*/
public synchronized final CustomCountDownTimer start() {
mCancelled = false;
mPause = false;
if (mMillisInFuture <= 0) {
onFinish();
return this;
}
mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
mHandler.sendMessage(mHandler.obtainMessage(MSG));
return this;
}
/**
* Callback fired on regular interval.
*
* #param millisUntilFinished The amount of time until finished.
*/
public abstract void onTick(long millisUntilFinished);
/**
* Callback fired when the time is up.
*/
public abstract void onFinish();
private static final int MSG = 1;
// handles counting down
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
synchronized (CustomCountDownTimer.this) {
if (mCancelled || mPause) {
return;
}
final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
Log.d(TAG, "millisLeft: " + millisLeft);
if (millisLeft <= 0) {
onFinish();
} else if (millisLeft < mCountdownInterval) {
// no tick, just delay until done
sendMessageDelayed(obtainMessage(MSG), millisLeft);
} else {
long lastTickStart = SystemClock.elapsedRealtime();
onTick(millisLeft);
// take into account user's onTick taking time to execute
long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();
// special case: user's onTick took more than interval to
// complete, skip to next interval
while (delay < 0) delay += mCountdownInterval;
sendMessageDelayed(obtainMessage(MSG), delay);
}
}
}
};
}

How to implement coundowntimer to run beyond the limit?

i am working on a application in which i am using CountDownTimer for timer purpose which runs from the start time given to upto 0 and then receives a callback in onFinish(), but i want it to run in negative value. say, if timer is set for 1 minutes and its over then it should continue in -ve value instead of stooping the countdowntimer .
How to do that, or is there any other way to do it ?
Sorry for late answer but I hope this will helpful someone who also whats to do same as this question.
Fist android provide CountDownTimer class to perform count down timer operation. In this class timer stop while time is 0 hour, 0 minute, 0 second and onFinish() method call.
so If we want to go in minus value we need some line to comment out means in other word we have to make our custom class for count down timer. so here is custom class which can goes in minus value also. Just past it in your project and import this class instead of original CountDownTimer class.
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
public abstract class CustomCountDownTimer {
/**
* Millis since epoch when alarm should stop.
*/
private final long mMillisInFuture;
/**
* The interval in millis that the user receives callbacks
*/
private final long mCountdownInterval;
private long mStopTimeInFuture;
/**
* boolean representing if the timer was cancelled
*/
private boolean mCancelled = false;
/**
* #param millisInFuture The number of millis in the future from the call
* to {#link #start()} until the countdown is done and {#link #onFinish()}
* is called.
* #param countDownInterval The interval along the way to receive
* {#link #onTick(long)} callbacks.
*/
public CustomCountDownTimer(long millisInFuture, long countDownInterval) {
mMillisInFuture = millisInFuture;
mCountdownInterval = countDownInterval;
}
/**
* Cancel the countdown.
*/
public synchronized final void cancel() {
mCancelled = true;
mHandler.removeMessages(MSG);
}
/**
* Start the countdown.
*/
public synchronized final CustomCountDownTimer start() {
mCancelled = false;
//if (mMillisInFuture <= 0) {
//onFinish();
//return this;
//}
mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
mHandler.sendMessage(mHandler.obtainMessage(MSG));
return this;
}
/**
* Callback fired on regular interval.
*
* #param millisUntilFinished The amount of time until finished.
*/
public abstract void onTick(long millisUntilFinished);
/**
* Callback fired when the time is up.
*/
public abstract void onFinish();
private static final int MSG = 1;
// handles counting down
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
synchronized (CustomCountDownTimer.this) {
if (mCancelled) {
return;
}
final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
//if (millisLeft <= 0) {
// onFinish();
//} else
// if (millisLeft < mCountdownInterval) {
// no tick, just delay until done
// sendMessageDelayed(obtainMessage(MSG), millisLeft);
// } else {
long lastTickStart = SystemClock.elapsedRealtime();
onTick(millisLeft);
// take into account user's onTick taking time to execute
long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();
// special case: user's onTick took more than interval to
// complete, skip to next interval
while (delay < 0) delay += mCountdownInterval;
sendMessageDelayed(obtainMessage(MSG), delay);
// }
}
}
};
}
important : here we remove onFinish() method from condition so it won't be finish you have to call onFinsh() method as per your requrement

Keep Timer Ticking in Background

How can I keep the value of my timer resuming after going to another activity , my problem is that it's set to default if I switched to another activity I thought of using sharedpreference but it won't help because I need it to keep decrementing in the background.
public void reset()
{
countDownTimer.cancel();
}
private void setTimer() {
int time = 5;
if(countDownTimer==null)
{
totalTimeCountInMilliseconds = 60 * time * 1000;
}
else
{
reset();
totalTimeCountInMilliseconds = 60 * time * 1000;
}
}
private void startTimer() {
countDownTimer = new CountDownTimer(totalTimeCountInMilliseconds, 500) {
// 500 means, onTick function will be called at every 500
// milliseconds
//#Override
public void onTick(long leftTimeInMilliseconds) {
seconds = leftTimeInMilliseconds / 1000;
textViewShowTime.setText(String.format("%02d", seconds / 60)
+ ":" + String.format("%02d", seconds % 60));
// format the textview to show the easily readable format
}
#Override
public void onFinish() {
// this function will be called when the timecount is finished
textViewShowTime.setText("Time up!");
textViewShowTime.setVisibility(View.VISIBLE);
}
}.start();
}
You should stop your CountDownTimer in onPause and restart in onResume, your textViewShowTime might not be valid while your activity is in background.
If you need to call some code every 500ms no matter what activity you are in, then consider using AlarmManager.

Pause CountDownTimer in Android when activity is not in front

I have an activity that uses a CountDownTimer that counts down from 10. How do I pause that timer when the activity is no longer in focus, like if the user get a call or something, then resume the timer when the user goes back to the activity? Is this even possible?
I would add something to the onTick handler to save the progress of the timer in your class (number of milliseconds left).
In the onPause() method for the activity call cancel() on the timer.
In the onResume() method for the activity create a new timer with the saved number of milliseconds left.
You can use pause() to pause the timer and later on Start or Resume the countDownTimer by calling start().
/**
* This class uses the native CountDownTimer to
* create a timer which could be paused and then
* started again from the previous point. You can
* provide implementation for onTick() and onFinish()
* then use it in your projects.
*/
public abstract class CountDownTimerPausable {
long millisInFuture = 0;
long countDownInterval = 0;
long millisRemaining = 0;
CountDownTimer countDownTimer = null;
boolean isPaused = true;
public CountDownTimerPausable(long millisInFuture, long countDownInterval) {
super();
this.millisInFuture = millisInFuture;
this.countDownInterval = countDownInterval;
this.millisRemaining = this.millisInFuture;
}
private void createCountDownTimer(){
countDownTimer = new CountDownTimer(millisRemaining,countDownInterval) {
#Override
public void onTick(long millisUntilFinished) {
millisRemaining = millisUntilFinished;
CountDownTimerPausable.this.onTick(millisUntilFinished);
}
#Override
public void onFinish() {
CountDownTimerPausable.this.onFinish();
}
};
}
/**
* Callback fired on regular interval.
*
* #param millisUntilFinished The amount of time until finished.
*/
public abstract void onTick(long millisUntilFinished);
/**
* Callback fired when the time is up.
*/
public abstract void onFinish();
/**
* Cancel the countdown.
*/
public final void cancel(){
if(countDownTimer!=null){
countDownTimer.cancel();
}
this.millisRemaining = 0;
}
/**
* Start or Resume the countdown.
* #return CountDownTimerPausable current instance
*/
public synchronized final CountDownTimerPausable start(){
if(isPaused){
createCountDownTimer();
countDownTimer.start();
isPaused = false;
}
return this;
}
/**
* Pauses the CountDownTimerPausable, so it could be resumed(start)
* later from the same point where it was paused.
*/
public void pause()throws IllegalStateException{
if(isPaused==false){
countDownTimer.cancel();
} else{
throw new IllegalStateException("CountDownTimerPausable is already in pause state, start counter before pausing it.");
}
isPaused = true;
}
public boolean isPaused() {
return isPaused;
}
}
No need to create a new Timer, just set the millisUntilFinished = total. For instance
private CountDownTimer cdTimer;
private long total = 30000;
...
toggleButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view){
if(toggleButton.isChecked()) {
startCountDownTimer();
}else{
cdTimer.cancel();
}
}
});
...
private void startCountDownTimer() {
cdTimer = new CountDownTimer(total, 1000) {
public void onTick(long millisUntilFinished) {
//update total with the remaining time left
total = millisUntilFinished;
nTimeLabel.setText("seconds remaining: " + millisUntilFinished/ 1000);
}
public void onFinish() {
nTimeLabel.setText("done!");
}
}.start();
}
This must be exactly what you're looking for. Source is this Gist.
package alt.android.os;
import android.os.Handler;
import android.os.SystemClock;
import android.os.Message;
public abstract class CountDownTimer {
/**
* Millis since epoch when alarm should stop.
*/
private final long mMillisInFuture;
/**
* The interval in millis that the user receives callbacks
*/
private final long mCountdownInterval;
private long mStopTimeInFuture;
private long mPauseTime;
private boolean mCancelled = false;
private boolean mPaused = false;
/**
* #param millisInFuture The number of millis in the future from the call
* to {#link #start()} until the countdown is done and {#link #onFinish()}
* is called.
* #param countDownInterval The interval along the way to receive
* {#link #onTick(long)} callbacks.
*/
public CountDownTimer(long millisInFuture, long countDownInterval) {
mMillisInFuture = millisInFuture;
mCountdownInterval = countDownInterval;
}
/**
* Cancel the countdown.
*
* Do not call it from inside CountDownTimer threads
*/
public final void cancel() {
mHandler.removeMessages(MSG);
mCancelled = true;
}
/**
* Start the countdown.
*/
public synchronized final CountDownTimer start() {
if (mMillisInFuture <= 0) {
onFinish();
return this;
}
mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
mHandler.sendMessage(mHandler.obtainMessage(MSG));
mCancelled = false;
mPaused = false;
return this;
}
/**
* Pause the countdown.
*/
public long pause() {
mPauseTime = mStopTimeInFuture - SystemClock.elapsedRealtime();
mPaused = true;
return mPauseTime;
}
/**
* Resume the countdown.
*/
public long resume() {
mStopTimeInFuture = mPauseTime + SystemClock.elapsedRealtime();
mPaused = false;
mHandler.sendMessage(mHandler.obtainMessage(MSG));
return mPauseTime;
}
/**
* Callback fired on regular interval.
* #param millisUntilFinished The amount of time until finished.
*/
public abstract void onTick(long millisUntilFinished);
/**
* Callback fired when the time is up.
*/
public abstract void onFinish();
private static final int MSG = 1;
// handles counting down
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
synchronized (CountDownTimer.this) {
if (!mPaused) {
final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
if (millisLeft <= 0) {
onFinish();
} else if (millisLeft < mCountdownInterval) {
// no tick, just delay until done
sendMessageDelayed(obtainMessage(MSG), millisLeft);
} else {
long lastTickStart = SystemClock.elapsedRealtime();
onTick(millisLeft);
// take into account user's onTick taking time to execute
long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();
// special case: user's onTick took more than interval to
// complete, skip to next interval
while (delay < 0) delay += mCountdownInterval;
if (!mCancelled) {
sendMessageDelayed(obtainMessage(MSG), delay);
}
}
}
}
}
};
}
You can try using Hourglass
Hourglass hourglass = new Hourglass(50000, 1000) {
#Override
public void onTimerTick(long timeRemaining) {
// Update UI
Toast.show(MainActivity.this, String.valueOf(timeRemaining), Toast.LENGTH_SHORT).show();
}
#Override
public void onTimerFinish() {
// Timer finished
Toast.show(MainActivity.this, "Timer finished", Toast.LENGTH_SHORT).show();
}
};
Use hourglass.startTimer(); to start the timer.
It has helper methods which allow to pause and resume the timer.
hourglass.pauseTimer();
AND
hourglass.resumeTimer();
Here is the code below .Use it in your activities it works fine.
public class MainActivity extends AppCompatActivity {
TextView textview;
final static long INTERVAL = 1000;
final static long TIMEOUT = 11000;
static long millisecondsleft;
boolean isPause =false;
CountDownTimer countDownTimer;
CountDownTimer countDownTimeronResume;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textview=findViewById(R.id.textviewcheck);
}
#Override
protected void onResume() {
super.onResume();
if(isPause == false) {
countDownTimer = new CountDownTimer(TIMEOUT, INTERVAL) {
#Override
public void onTick(long millisUntilFinished) {
millisecondsleft = millisUntilFinished;
textview.setText(":" + String.format("%02d", millisUntilFinished / 1000));
}
#Override
public void onFinish() {
textview.setText("DONE!");
}
}.start();
} else{
countDownTimeronResume = new CountDownTimer(millisecondsleft, INTERVAL) {
#Override
public void onTick(long millisUntilFinished) {
Toast.makeText(MainActivity.this, "ONPAUSED", Toast.LENGTH_SHORT).show();
millisecondsleft = millisUntilFinished;
textview.setText(":" + String.format("%02d", millisUntilFinished / 1000));
}
#Override
public void onFinish() {
textview.setText("DONE!");
}
}.start();
}
}
#Override
protected void onPause() {
super.onPause();
if(countDownTimer!=null){
countDownTimer.cancel();
isPause = true;
}
if(countDownTimeronResume!=null){
countDownTimeronResume.cancel();
}
}
}
For Kotlin user, checkout this
For eg:
// Init timer
lateinit var timerExt: CountDownTimerExt
timerExt = object : CountDownTimerExt(TIMER_DURATION, TIMER_INTERVAL) {
override fun onTimerTick(millisUntilFinished: Long) {
Log.d("MainActivity", "onTimerTick $millisUntilFinished")
}
override fun onTimerFinish() {
Log.d("MainActivity", "onTimerFinish")
}
}
// Start/Resume timer
timerExt.start()
// Pause timer
timerExt.pause()
// Restart timer
timerExt.restart()

Categories

Resources