In this tutorial you’ll learn how to create a basic Progress Notification (Indeterminate progress indicator and Fixed-duration progress indicator) for Android using Kotlin.
Before we begin, let us first understand the components of a Notification in Android.
![]()

![]()
- Small Icon – Required, can be set with setSmallIcon().
- Application Name – Provided by the system.
- Time Stamp – Provided by the system but can be overridden.
- Large Icon – Optional, can be set with setLargeIcon().
- Title – Optional, can be set with setContentTitle().
- Text – Optional, can be set with setContentText().
Note : Notification Channels
Since the introduction of Android version 8 (Android Oreo), it is now compulsory to categorize all the notifications into categories called ‘channels’, this is for the convenience of users and also developers.
The image below shows us a notification channel named ‘Progress Notification’.
![]()

![]()
Since we only need to create a channel once, we’ll use a helper class ‘App.kt’ to get the job done.
App.kt
package com.gfg.progressnotificationdemo import android.app.Application import android.app.NotificationChannel import android.app.NotificationManager import android.os.Build class App : Application(){ val channelId = "Progress Notification" as String override fun onCreate(){ super.onCreate() createNotificationChannels() } //Check if the Android version is greater than 8. (Android Oreo) private fun createNotificationChannels(){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel1 = NotificationChannel( channelId, "Progress Notification", //IMPORTANCE_HIGH = shows a notification as peek notification. //IMPORTANCE_LOW = shows the notification in the status bar. NotificationManager.IMPORTANCE_HIGH ) channel1.description = "Progress Notification Channel" val manager = getSystemService( NotificationManager::class.java ) manager.createNotificationChannel(channel1) } } } |
![]()
Now, in the main activity we'll use a thread to invoke the notification.
![]()
MainActivity.kt
package com.gfg.progressnotificationdemo import android.app.PendingIntent import android.content.Intent import android.os.Bundle import android.os.SystemClock import android.view.View import androidx.appcompat.app.AppCompatActivity import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import com.gfg.progressnotificationdemo.R.drawable class MainActivity : AppCompatActivity(){ private lateinit var notificationManager: NotificationManagerCompat val channelId = "Progress Notification" as String override fun onCreate(savedInstanceState: Bundle?){ super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) //Create a Notification Manager notificationManager = NotificationManagerCompat.from(this) } //Start() is called when the buttons is pressed. public fun start(view: View){ val intent = Intent(this, MainActivity::class.java).apply{ flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK } val pendingIntent: PendingIntent = PendingIntent.getActivity( this, 0, intent, 0) //Sets the maximum progress as 100 val progressMax = 100 //Creating a notification and setting its various attributes val notification = NotificationCompat.Builder(this, channelId) .setSmallIcon(drawable.ic_file_download) .setContentTitle("GeeksforGeeks") .setContentText("Downloading") .setPriority(NotificationCompat.PRIORITY_LOW) .setOngoing(true) .setOnlyAlertOnce(true) .setProgress(progressMax, 0, true) .setContentIntent(pendingIntent) .setAutoCancel(true) //Initial Alert notificationManager.notify(1, notification.build()) Thread(Runnable{ SystemClock.sleep(2000) var progress = 0 while (progress <= progressMax) { SystemClock.sleep( 1000 ) progress += 20 //Use this to make it a Fixed-duration progress indicator notification //notification.setContentText(progress.toString()+"%") //.setProgress(progressMax, progress, false) //notificationManager.notify(1, notification.build()) } notification.setContentText("Download complete") .setProgress(0, 0, false) .setOngoing(false) notificationManager.notify(1, notification.build()) }).start() } } |
Activity Main.xml
Layout consists of a single button.
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="75dp" android:onClick="start" android:text="Show Notification" android:textSize="22sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> |
![]()
Output:
- Fixed-duration progress indicator : (after adding code in comments at line 67 of MainActivity.kt)


- Indeterminate progress indicator :


- After Download :


That’s how easy and simple it is to add progress indicator to a notification in Android using Kotlin.
Recommended Posts:
- Notifications in Kotlin
- How to create project in Android Studio using Kotlin
- Android EditText in Kotlin
- Android LinearLayout in Kotlin
- Android RelativeLayout in Kotlin
- Android ListView in Kotlin
- Android FrameLayout in Kotlin
- Android TableLayout in Kotlin
- Android Toast in Kotlin
- Android Fade In/Out in Kotlin
- Android Slide Up/Down in Kotlin
- Android Animations in Kotlin
- Kotlin Android Tutorial
- Difference between Java and Kotlin in Android with Examples
- Why You Should Switch to Kotlin from Java to Develop Android Apps?
- How to send message on WhatsApp in Android using Kotlin
- Thread Priority in Kotlin & Android
- Running User Interface Thread in Android using Kotlin
- How to Add RangeSeekbar in Android Using Kotlin?
- Android WebView in Kotlin
If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

