Notification Channel Utility Class For Android Notifications

Android Oreo 8.0 has been around for a while, offering so many new features like Notification Bar Style, Battery Life Optimization, Automatic Adjustment of TextView, Downloadable Fonts & Emotions, Adaptive Icons and many more. Now in this post, we specifically look at one of exciting feature which is Notification Channels.

 If you want to cover the Downloadable Fonts and Emotions then see this article => Android Emoji Compat

You may have searched for Notification Channels on the internet to find an example which works well on both new and older API levels. Luckily! I happen to write a pretty good utility class for notifications. This utility class uses Notification Channels for API level 26 or above falling back the older method on all API levels.

Notification Channel

Before showing you the utility class for notifications I think intro on the Notification Channels is necessary.

Brief Intro On Notification Channel

Notification Channel are somewhat like groups of categories of notification, all notifications that are posted on the same channel have the same behavior.  For example, for each channel, users can completely block all notifications, override the importance level, or allow a notification badge to be shown. This new feature helps in greatly improving the user experience of an app.

Notification Helper Class

class NotificationHelper constructor(context: Context) : ContextWrapper(context) {

    private val notificationManager: NotificationManager =
        getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

    companion object {
        private const val MESSAGE_NOTIFICATION_TITLE = "Message Notification Channel"
        private const val COMMENT_NOTIFICATION_TITLE = "Comment Notification Channel"
        private const val DEFAULT_NOTIFICATION_TITLE = "Application Notification"
        const val MESSAGE_NOTIFICATION_CHANNEL = "your.package.name.message_channel"
        const val COMMENT_NOTIFICATION_CHANNEL = "your.package.name.comment_channel"
        private const val DEFAULT_NOTIFICATION_CHANNEL = "your.project.name.default_channel"
    }

    init {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
            createChannels()
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private fun createChannels() {
        val uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
        val notificationChannels = mutableListOf<NotificationChannel>()

         // Building message notification channel
       
        val messageNotificationChannel = NotificationChannel(
            MESSAGE_NOTIFICATION_CHANNEL,
            MESSAGE_NOTIFICATION_TITLE, NotificationManager.IMPORTANCE_HIGH
        )
        messageNotificationChannel.enableLights(true)
        messageNotificationChannel.lightColor = Color.RED
        messageNotificationChannel.setShowBadge(true)
        messageNotificationChannel.setSound(uri, null)
        messageNotificationChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
        notificationChannels.add(messageNotificationChannel)

        // Building comment notification channel
        
        val commentNotificationChannel = NotificationChannel(
            COMMENT_NOTIFICATION_CHANNEL,
            COMMENT_NOTIFICATION_TITLE, NotificationManager.IMPORTANCE_HIGH
        )
        commentNotificationChannel.enableLights(true)
        commentNotificationChannel.lightColor = Color.RED
        commentNotificationChannel.setShowBadge(true)
        commentNotificationChannel.setSound(uri, null)
        commentNotificationChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
        notificationChannels.add(commentNotificationChannel)

        // Building default notification channel

        val defaultNotificationChannel = NotificationChannel(
            DEFAULT_NOTIFICATION_CHANNEL,
            DEFAULT_NOTIFICATION_TITLE, NotificationManager.IMPORTANCE_LOW
        )
        defaultNotificationChannel.setShowBadge(true)
        defaultNotificationChannel.setSound(uri, null)
        notificationChannels.add(defaultNotificationChannel)

        notificationManager.createNotificationChannels(notificationChannels)
    }

    fun createNotificationBuilder(title: String, body: String, cancelAble: Boolean = true, pendingIntent: PendingIntent? = null,channelId: String = DEFAULT_NOTIFICATION_CHANNEL
    ): Notification.Builder {
        val builder: Notification.Builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
            Notification.Builder(applicationContext, channelId)
        else
            Notification.Builder(applicationContext)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            builder.setSmallIcon(R.mipmap.app_icon)
            builder.setColor(ContextCompat.getColor(applicationContext, R.color.colorPrimary))
        } else
            builder.setSmallIcon(R.mipmap.app_icon)
        if (pendingIntent != null)
            builder.setContentIntent(pendingIntent)
        builder.setContentTitle(title)
            .setContentText(body)
            .setStyle(Notification.BigTextStyle().bigText(body))
            .setAutoCancel(cancelAble)
        return builder
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    fun deleteChannel(channelId: String) = apply {
        notificationManager.deleteNotificationChannel(channelId)
    }

    fun makeNotification(builder: Notification.Builder, notificationId: Int) = apply {
        notificationManager.notify(notificationId, builder.build())
    }

    fun cancelNotification(notificationId: Int) = apply {
        notificationManager.cancel(notificationId)
    }
}

Here, we have created the NotificationHelper class that requires the Context as the constructor params. In  initializer block, we simply create our Notification Channels if the SDK version is greater than or equal to Android O .

The method createChannels creates the Notification Channels and add the notification channels into NotificationManager. Channel creation requires a unique name and ID and a level of importance. The uniqueness of the name and ID only refers to your app package. The NotificationManager then does the creation of the channel with whatever settings you specify.

The method createNotificationBuilder requires title and body parameters in order to set the title and content text of the notification. Some additional parameter like pendingIntent for redirecting the page when a user clicks on the notification.

The makeNotification method requires NotificationId and builder parameters in order to create the notification.

Finally, the cancelNotification method takes the notificationId and cancel the notification associated with this Id.

Now that we’ve created our notification utility class. It’s time to see how we can create a notification. The following shows the example to create a notification.

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)        
        val notificationHelper = NotificationHelper(this)
        val builder = notificationHelper.createNotificationBuilder(
            "Comments Received",
            "Jack has recently commented on your post!"
        )
        notificationHelper.makeNotification(builder, someIntId)
    }
}

 

If you’ve any advice on how to make our Notification Channel helper class better or how to extend, do comment below and discuss it. 🙃

Thank you for being here and keep reading…

LEAVE A REPLY

Please enter your comment!
Please enter your name here