/*
 * 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 android.os;

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:
new CountDownTimer(30000, 1000) {
    public void onTick(long millisUntilFinished) {
        mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
    }
    public void onFinish() {
        mTextField.setText("done!");
    }
 }.start();
The calls to onTick(long) are synchronized to this object so that one call to onTick(long) won't ever occur before the previous callback is complete. This is only relevant when the implementation of onTick(long) takes an amount of time to execute that is significant compared to the countdown interval.
/** * 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.
/** * Millis since epoch when alarm should stop. */
private final long mMillisInFuture;
The interval in millis that the user receives callbacks
/** * The interval in millis that the user receives callbacks */
private final long mCountdownInterval; private long mStopTimeInFuture;
boolean representing if the timer was cancelled
/** * boolean representing if the timer was cancelled */
private boolean mCancelled = false;
Params:
  • millisInFuture – The number of millis in the future from the call to start() until the countdown is done and onFinish() is called.
  • countDownInterval – The interval along the way to receive onTick(long) callbacks.
/** * @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.
/** * Cancel the countdown. */
public synchronized final void cancel() { mCancelled = true; mHandler.removeMessages(MSG); }
Start the countdown.
/** * Start the countdown. */
public synchronized final CountDownTimer 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.
Params:
  • millisUntilFinished – The amount of time until finished.
/** * 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.
/** * 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 (mCancelled) { return; } final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime(); if (millisLeft <= 0) { onFinish(); } else { long lastTickStart = SystemClock.elapsedRealtime(); onTick(millisLeft); // take into account user's onTick taking time to execute long lastTickDuration = SystemClock.elapsedRealtime() - lastTickStart; long delay; if (millisLeft < mCountdownInterval) { // just delay until done delay = millisLeft - lastTickDuration; // special case: user's onTick took more than interval to // complete, trigger onFinish without delay if (delay < 0) delay = 0; } else { delay = mCountdownInterval - lastTickDuration; // special case: user's onTick took more than interval to // complete, skip to next interval while (delay < 0) delay += mCountdownInterval; } sendMessageDelayed(obtainMessage(MSG), delay); } } } }; }