Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
710 views
in Technique[技术] by (71.8m points)

time - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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);
                }
            }
        }
    };
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...