Skip to main content

Notification Channels

Notification channel (or notification category) is introduced in Android 8.0 (API level 26). Notification channel is a collection of associated notifications. It offers fine-grained notification control to users through consistent settings UI.

Starting from Android 8.0, notifications must be assigned to a notification channel. Otherwise, the notification won't show up and your app will get an error.

Here's an example of list of notification channels in Chrome application in Android 13 (API level 33):

The notifications channels are "Browser", "Active downloads", "Incognito", and "Playing media."

If you tap on one of the notification channels, user will be redirected to the notification channel setting page:

Basic Usages​

There are a few things you can do related to notification channels as developers.

Opening Notification Channel Setting Page​

You can programmatically open your app's notification channel setting page by using ACTION_CHANNEL_NOTIFICATION_SETTINGS intent action:

import android.content.Context
import android.content.Intent
import android.os.Build
import android.provider.Settings
import androidx.core.content.ContextCompat.startActivity

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startActivity(
context,
Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS).apply {
putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
putExtra(Settings.EXTRA_CHANNEL_ID, channelId) // Your notification channel ID
},
null,
)
}

Opening Notification Channel Setting Bottomsheet​

In Android 11 (API level 31), you can also open only the selected settings of the notification channel in a bottomsheet by putting EXTRA_CHANNEL_FILTER_LIST extra to the ACTION_CHANNEL_NOTIFICATION_SETTINGS intent:

import android.app.NotificationChannel
import android.content.Context
import android.content.Intent
import android.os.Build
import android.provider.Settings
import androidx.core.content.ContextCompat.startActivity

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startActivity(
context,
Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS).apply {
putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
putExtra(Settings.EXTRA_CHANNEL_ID, channelId)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
putExtra(
Settings.EXTRA_CHANNEL_FILTER_LIST,
arrayListOf(
NotificationChannel.EDIT_LAUNCHER,
),
)
}
},
null,
)
}

The code above will show a notification channel setting bottomsheet that only shows settings related to launcher behavior (showing badges/dots) like this:

You can show different settings based on the extra value:

Extra valueScreenshot
EDIT_LAUNCHER
EDIT_IMPORTANCE
EDIT_LOCKED_DEVICE
EDIT_SOUND
EDIT_VIBRATION
EDIT_ZEN
EDIT_CONVERSATIONNot yet available

Creating Notification Channel​

You can create a notification channel for your application programmatically by using createNotificationChannel() method. Or alternatively, if you want to create multiple notification channels simultaneously, you can use createNotificationChannels() method instead.

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channelId = "channel-latest-news"
val name = "Latest News & Info"
val channel = NotificationChannel(
channelId,
name,
NotificationManager.IMPORTANCE_DEFAULT,
).apply {
description = "Notify user about the latest news & information about Android Notebook."
}

val notificationManager = context.getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(channel)
}

Getting All Application Notification Channels​

You can retrieve all of your application's notification channels by using getNotificationChannels() method:

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationManager = context.getSystemService(NotificationManager::class.java)
val notificationChannels = notificationManager.notificationChannels
}

Getting Notification Channel by ID​

You can retrieve a notification channel by its channel id by using getNotificationChannel() method:

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channelId = "channel-latest-news"
val notificationManager = context.getSystemService(NotificationManager::class.java)
val notificationChannel = notificationManager.getNotificationChannel(channelId)
}

If the notification channel doesn't exist or has been deleted, this method will return null.

Deleting Notification Channel​

You can delete your application's notification channel by using deleteNotificationChannel() method:

import android.app.NotificationManager
import android.content.Context
import android.os.Build

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationManager = context.getSystemService(NotificationManager::class.java)
notificationManager.deleteNotificationChannel(channelId)
}

This method will soft-delete the specified notification channel. If you create a notification channel with the same channel id, then the deleted channel will be un-deleted.

Listening to Notification Channel Block State​

You can also listen to a broadcast intent whenever your application's notification channel is blocked/unblocked by the user. To do this, you can create a broadcast receiver and listen to ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED intent action:

NotificationChannelBlockStateBroadcastReceiver.kt
package com.hanmajid.androidnotebook

import android.app.NotificationManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log

/**
* Simple broadcast receiver that listens to [NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED]
* intent action.
*/
class NotificationChannelBlockStateBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val notificationChannelId = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
intent.getStringExtra(NotificationManager.EXTRA_NOTIFICATION_CHANNEL_ID)
} else {
null
}
val isBlocked = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
intent.getBooleanExtra(NotificationManager.EXTRA_BLOCKED_STATE, false)
} else {
null
}
Log.i("TAG", "notificationChannelId: $notificationChannelId")
Log.i("TAG", "isBlocked: $isBlocked")
}
}

Then you can register the broadcast receiver within your context:

import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import androidx.core.content.ContextCompat

// Initialize broadcast receiver within your context.
val broadcastReceiver = NotificationChannelBlockStateBroadcastReceiver()

// Register broadcast receiver to [context].
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
ContextCompat.registerReceiver(
context,
broadcastReceiver,
IntentFilter(NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED),
ContextCompat.RECEIVER_NOT_EXPORTED,
)
}

Properties​

Notification channel has several properties that we can customize.

Importance​

Notification channel's importance specifies the level of interruption of the channel. There are several level of importances that we can choose (from highest to lowest):

Importance LevelThe ResultUser-visible Importance Level
IMPORTANCE_HIGHUrgent: Makes a sound and appears as a heads-up notification.
IMPORTANCE_DEFAULTHigh: Makes a sound.
IMPORTANCE_LOWMedium: Makes no sound.
IMPORTANCE_MINLow: Makes no sound and doesn't appear in the status bar.
IMPORTANCE_NONENone: Makes no sound and doesn't appear in the status bar or shade.

Some devices support showing a blink light when they received a notification. We can enable/disable notification light for our notification channels by using enableLights() method:

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channelId = "channel-latest-news"
val name = "Latest News & Info"
val channel = NotificationChannel(
channelId,
name,
NotificationManager.IMPORTANCE_DEFAULT,
).apply {
description = "Notify user about the latest news & information about Android Notebook."
enableLights(true)
}

val notificationManager = context.getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(channel)
}

This property is only modifiable before the channel is submitted to createNotificationChannel().

References​