How to create Countdown Timer on Android

How to create Countdown Timer on Android

Countdown Timer

A countdown is a sequence of backward counting to indicate the time remaining before an event is scheduled to occur. To achieve countdown Android comes with a built-in CountDownTimer class for constructing countdown timer. This class is an abstract class whose methods need to be overridden to implement it in our project.

Implementing a countdown timer in your app won’t take more than two steps. First you need to create an object of in-built abstract class named CountDownTimer. This class is used to schedule a countdown until a time in the future, with regular notifications on intervals along the way.

CountDownTimer countDownTimer = new CountDownTimer(60000, 1000) {
    public void onTick(long millisUntilFinished) {
        tvTimer.setText("Seconds Remaining: " + millisUntilFinished / 1000);
    }

    public void onFinish() {
        tvTimer.setText("Time Up!");
    }
};

Second you have to start the countdown timer via invoking start() method.

countDownTimer.start();

The relevant methods of the CountDownTimer class are given below.

  • synchronized final void cancel(). This is used to cancel the countdown.
  • abstract void onFinish(). This callback method is fired when the timer finishes.
  • abstract void onTick(long millisUntilFinished). This callback method is fired on regular intervals.
  • synchronized final CountDownTimer start(). This method is used to start the countdown.
  • CountDownTimer(long millisInFuture, long countDownInterval). This method is signature of the public constructor. Here millisInFuture is the time you set in millisecond when you want CountDownTimer to stop and countDownInterval is the interval time in millisecond you set after which number will increment in CountDownTimer.

Following is layout for example

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="5dp">

    <TextView
        android:text="00:00:00"
        android:id="@+id/tvTimer"
        android:textSize="40sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"/>

    <ProgressBar
        android:id="@+id/pbTime"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/tvTimer"
        android:layout_marginBottom="10dp"
        android:max="100"
        android:progress="100"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/pbTime"
        android:layout_alignParentLeft="true"
        android:onClick="start"
        android:text="Start"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/pbTime"
        android:layout_alignParentRight="true"
        android:onClick="stop"
        android:text="Stop"/>

</RelativeLayout>

Following is MainActivity.java

public class SixActivity extends AppCompatActivity {
    TextView tvTimer;
    CountDownTimer countDownTimer;
    private ProgressBar pbTime;
    int time = 4 * 60 * 1000; // 4 minutes
    int interval = 1000; // 1 second

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_six);

        tvTimer = (TextView) findViewById(R.id.tvTimer);
        pbTime = (ProgressBar) findViewById(R.id.pbTime);

        setProgressBarValues();

        countDownTimer = new CountDownTimer(time, interval) {
            public void onTick(long millisUntilFinished) {
                tvTimer.setText(getDateFromMillis(millisUntilFinished));
                int progress = (int) millisUntilFinished / interval;
                pbTime.setProgress(pbTime.getMax() - progress);
//                pbTime.setProgress((int) (millisUntilFinished / interval));
            }

            public void onFinish() {
                tvTimer.setText("00:00:00");
                setProgressBarValues();
            }
        };
    }

    public static String getDateFromMillis(long d) {
        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
        df.setTimeZone(TimeZone.getTimeZone("GMT"));
        return df.format(d);
    }

    private void setProgressBarValues() {
        pbTime.setMax(time / interval);
        pbTime.setProgress(time / interval);
    }

    public void start(View v) {
        setProgressBarValues();
        countDownTimer.start();
    }

    public void stop(View v) {
        countDownTimer.cancel();
    }
}

Result

android_countdown_timer.png

Timer

In this example we are going to create a simple Android Timer application. We are going to use some very basic ideas and tools, like Handler, that you can use in many cases in your Applications.

Following layout is very simple

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="5dp">

    <TextView
        android:text="00:00:00"
        android:id="@+id/tvTimer"
        android:textSize="40sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tvTimer"
        android:layout_alignParentLeft="true"
        android:onClick="start"
        android:text="Start"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tvTimer"
        android:layout_alignParentRight="true"
        android:onClick="stop"
        android:text="Stop"/>

</RelativeLayout>

Following is MainActivity.java

public class SixActivity extends AppCompatActivity {
    TextView tvTimer;
    long startTime, timeInMilliseconds = 0;
    Handler customHandler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_six);

        tvTimer = (TextView) findViewById(R.id.tvTimer);
    }

    public static String getDateFromMillis(long d) {
        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
        df.setTimeZone(TimeZone.getTimeZone("GMT"));
        return df.format(d);
    }

    public void start(View v) {
        startTime = SystemClock.uptimeMillis();
        customHandler.postDelayed(updateTimerThread, 0);
    }

    public void stop(View v) {
        customHandler.removeCallbacks(updateTimerThread);
    }

    private Runnable updateTimerThread = new Runnable() {
        public void run() {
            timeInMilliseconds = SystemClock.uptimeMillis() - startTime;
            tvTimer.setText(getDateFromMillis(timeInMilliseconds));
            customHandler.postDelayed(this, 1000);
        }
    };
}

The code of this section is pretty much self explanatory. The interesting part is how to update the value of the timer. We are going to use a Handler for that. The Handler takes a Runnable object and it schedules its execution; it places the runnable process as a job in an execution queue to be run after a specified amount of time. The Runnable will be run on the thread to which this handler is attached.

Result

android_timer.png
comments powered by Disqus