Kotlin Tutoial
Basics
Control Flow
Array & String
Functions
Collections
OOPs Concept
Exception Handling
Null Safety
Regex & Ranges
Java Interoperability
Miscellaneous
Android
Progress notifications are useful when you want to notify users about the progress of an ongoing task, such as downloading a file or uploading data. Android provides a flexible system to display and update notifications. In this tutorial, we'll demonstrate how to implement a progress notification using Kotlin.
Prerequisites:
1. Set up a new project:
Open Android Studio and create a new project. Choose an empty activity template.
2. Add the required permission:
In the AndroidManifest.xml
file, add the following permission (if your operation, e.g., a download, requires internet access):
<uses-permission android:name="android.permission.INTERNET" />
3. Create the Notification Channel:
Starting from Android Oreo (API 26), notification channels are required. In MainActivity.kt
, add:
private fun createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val name = "Progress Channel" val descriptionText = "Channel for progress notifications" val importance = NotificationManager.IMPORTANCE_LOW val channel = NotificationChannel("PROGRESS_CHANNEL_ID", name, importance).apply { description = descriptionText } val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(channel) } }
Call this method in your onCreate
method:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) createNotificationChannel() }
4. Implement the Progress Notification:
fun showProgressNotification() { val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager val builder = NotificationCompat.Builder(this, "PROGRESS_CHANNEL_ID") .setSmallIcon(R.drawable.ic_launcher_foreground) .setContentTitle("File Download") .setContentText("Download in progress") .setPriority(NotificationCompat.PRIORITY_LOW) .setOngoing(true) .setOnlyAlertOnce(true) .setProgress(100, 0, false) notificationManager.notify(1, builder.build()) // Simulate progress val maxProgress = 100 var currentProgress = 0 val handler = Handler(Looper.getMainLooper()) val runnable = object : Runnable { override fun run() { currentProgress += 10 if (currentProgress <= maxProgress) { builder.setProgress(maxProgress, currentProgress, false) notificationManager.notify(1, builder.build()) handler.postDelayed(this, 500) // update every half second } else { builder.setContentText("Download complete") .setProgress(0, 0, false) .setOngoing(false) notificationManager.notify(1, builder.build()) } } } handler.post(runnable) }
5. Triggering the Notification:
For demonstration purposes, add a button to your activity_main.xml
:
<Button android:id="@+id/startDownloadBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Start Download" android:layout_centerInParent="true"/>
Then in your MainActivity.kt
:
val startDownloadBtn = findViewById<Button>(R.id.startDownloadBtn) startDownloadBtn.setOnClickListener { showProgressNotification() }
6. Run the App:
When you click the "Start Download" button, the progress notification will appear and simulate a download process.
Notes:
Description: Indeterminate progress notifications display a spinning progress indicator, indicating that a task is ongoing but the progress is unknown.
Code (Notification creation with indeterminate progress):
val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.ic_notification) .setContentTitle("Downloading") .setContentText("File in progress") .setProgress(0, 0, true) // Indeterminate .setOngoing(true) val notificationManager = NotificationManagerCompat.from(this) notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build())
Description: Update the progress in ongoing notifications to reflect the current status of a task.
Code (Updating progress in an ongoing notification):
val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.ic_notification) .setContentTitle("Downloading") .setContentText("File in progress") .setProgress(100, progress, false) // Determinate progress .setOngoing(true) val notificationManager = NotificationManagerCompat.from(this) notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build())
Description: Customize the appearance of progress bar notifications by adjusting properties like color and style.
Code (Customizing progress bar in notification):
val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.ic_notification) .setContentTitle("Downloading") .setContentText("File in progress") .setProgress(100, progress, false) .setColor(ContextCompat.getColor(this, R.color.notification_color)) .setStyle(NotificationCompat.DecoratedCustomViewStyle()) .setCustomContentView(customView) // Your custom view for notification val notificationManager = NotificationManagerCompat.from(this) notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build())
Description: Handle multiple progress notifications by using unique notification IDs for each task.
Code (Handling multiple progress notifications):
val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.ic_notification) .setContentTitle("Task $taskId") .setContentText("Task in progress") .setProgress(100, progress, false) .setOngoing(true) val notificationManager = NotificationManagerCompat.from(this) notificationManager.notify(taskId, notificationBuilder.build())
Description: Determinate progress notifications display a progress bar with a specific completion percentage.
Code (Creating determinate progress notification):
val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.ic_notification) .setContentTitle("Uploading") .setContentText("File in progress") .setProgress(100, progress, false) // Determinate progress .setOngoing(true) val notificationManager = NotificationManagerCompat.from(this) notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build())
Description: Notification channels are used to group notifications. Define a channel for progress notifications.
Code (Creating a notification channel):
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( CHANNEL_ID, "Progress Notifications", NotificationManager.IMPORTANCE_LOW ) notificationManager.createNotificationChannel(channel) }
Description: Cancel or dismiss progress notifications when the associated task is completed or canceled.
Code (Canceling a notification):
val notificationManager = NotificationManagerCompat.from(this) notificationManager.cancel(NOTIFICATION_ID)
Description: Use a foreground service to perform tasks in the background while keeping the app in the foreground and displaying a progress notification.
Code (Starting a foreground service with progress notification):
val serviceIntent = Intent(this, YourForegroundService::class.java) serviceIntent.putExtra("inputExtra", "Foreground Service Example") ContextCompat.startForegroundService(this, serviceIntent)