How to Build a Countdown Timer in Android Using CountDownTimer
Countdown timers are commonly used in Android applications for:
- OTP verification screens
- Quiz applications
- Workout timers
- Pomodoro productivity apps
- Game countdown systems
Android provides a built-in class called CountDownTimer that helps developers implement countdown functionality easily.
In this tutorial, we will learn how to build a Countdown Timer in Android using the CountDownTimer class.
What Is CountDownTimer?
CountDownTimer is an Android utility class used to create timers that count down over a fixed interval.
It provides two important callback methods:
onTick()→ Called at regular intervalsonFinish()→ Called when timer completes
What We Will Build
In this Android example:
- User can start the timer
- User can pause the timer
- User can reset the timer
- Remaining time updates dynamically
Step 1 — Create activity_main.xml
Create the UI layout file.
<?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">
<TextView
android:id="@+id/text_view_countdown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="10:00"
android:textColor="@android:color/black"
android:textSize="60sp"/>
<Button
android:id="@+id/button_start_pause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/text_view_countdown"
android:layout_centerHorizontal="true"
android:text="Start"/>
<Button
android:id="@+id/button_reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/text_view_countdown"
android:layout_marginStart="12dp"
android:layout_toEndOf="@id/button_start_pause"
android:text="Reset"
android:visibility="gone"/>
</RelativeLayout>
Step 2 — Implement MainActivity.java
Open MainActivity.java and add the following code.
package com.example.countdowntimer;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
private static final long START_TIME_IN_MILLIS =
600000;
private TextView textViewCountDown;
private Button buttonStartPause;
private Button buttonReset;
private CountDownTimer countDownTimer;
private boolean timerRunning;
private long timeLeftInMillis =
START_TIME_IN_MILLIS;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textViewCountDown =
findViewById(R.id.text_view_countdown);
buttonStartPause =
findViewById(R.id.button_start_pause);
buttonReset =
findViewById(R.id.button_reset);
buttonStartPause.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (timerRunning) {
pauseTimer();
} else {
startTimer();
}
}
});
buttonReset.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
resetTimer();
}
});
updateCountDownText();
}
private void startTimer() {
countDownTimer =
new CountDownTimer(
timeLeftInMillis,
1000
) {
@Override
public void onTick(
long millisUntilFinished
) {
timeLeftInMillis =
millisUntilFinished;
updateCountDownText();
}
@Override
public void onFinish() {
timerRunning = false;
buttonStartPause.setText(
"Start"
);
buttonStartPause.setVisibility(
View.INVISIBLE
);
buttonReset.setVisibility(
View.VISIBLE
);
}
}.start();
timerRunning = true;
buttonStartPause.setText("Pause");
buttonReset.setVisibility(View.INVISIBLE);
}
private void pauseTimer() {
countDownTimer.cancel();
timerRunning = false;
buttonStartPause.setText("Start");
buttonReset.setVisibility(View.VISIBLE);
}
private void resetTimer() {
timeLeftInMillis =
START_TIME_IN_MILLIS;
updateCountDownText();
buttonReset.setVisibility(View.INVISIBLE);
buttonStartPause.setVisibility(View.VISIBLE);
}
private void updateCountDownText() {
int minutes =
(int) (timeLeftInMillis / 1000) / 60;
int seconds =
(int) (timeLeftInMillis / 1000) % 60;
String timeFormatted =
String.format(
Locale.getDefault(),
"%02d:%02d",
minutes,
seconds
);
textViewCountDown.setText(timeFormatted);
}
}
How This Countdown Timer Works
The workflow is:
- User clicks Start button
- CountDownTimer begins counting
- onTick() updates remaining time every second
- User can pause or reset timer
- onFinish() triggers after countdown completes
Understanding CountDownTimer Parameters
new CountDownTimer(totalTime, interval)
| Parameter | Description |
|---|---|
| totalTime | Total countdown duration |
| interval | Update interval frequency |
How Time Formatting Works
The timer stores values in milliseconds.
We convert milliseconds into:
- Minutes
- Seconds
Then format the output using:
String.format("%02d:%02d", minutes, seconds)
Common Mistakes Developers Make
1. Forgetting to Cancel Timer
Timers should be cancelled when no longer needed to avoid memory leaks.
2. Updating UI Incorrectly
UI updates should happen safely inside timer callbacks.
3. Not Handling Activity Lifecycle
Timers may continue running during Activity destruction if lifecycle handling is ignored.
Modern Android Improvements
Modern Android applications can improve this implementation using:
- Kotlin
- Coroutines
- Jetpack Compose
- ViewModel
- Lifecycle-aware timers
CountDownTimer vs Coroutines
| CountDownTimer | Coroutines |
|---|---|
| Simple built-in solution | Modern asynchronous approach |
| Limited lifecycle support | Lifecycle-aware architecture |
| Good for basic timers | Better for scalable apps |
FAQ
Can CountDownTimer run in background?
CountDownTimer is tied to the application process and is not ideal for long-running background timers.
Can I create custom intervals?
Yes. Developers can update timers at any interval such as 500ms or 1 second.
What is the modern alternative?
Kotlin Coroutines combined with ViewModel is the preferred modern solution.
Conclusion
Countdown timers are useful for many Android application features including OTP systems, quizzes, and productivity apps.
The CountDownTimer class provides a simple way to implement countdown functionality with regular UI updates.
Modern Android applications should combine timers with lifecycle-aware architecture for better scalability and reliability.
About the Author
Salil Jha is a Full Stack and Mobile Developer with experience in Android, React Native, scalable SaaS systems, fintech applications, and developer tooling platforms.
CodeChain Dev — Build Modern Products. Solve Real Problems.
Deep Structural Diagnostics.
Mastering JSON is only the first step. Use our industrial-grade workbench to format, validate, and synthesize models for your production APIs.