Creating Notifications in Android with Kotlin
Published: 2021-06-12 08:14:55

## STEPS

### *Create a Notification*

*NotificationUtils, EggTimerViewModel, EggTimerFragment*

***A Basic Notification***

- Implement an extension fun *sendN* in NotificationManager - to send Ns w/o rewriting the code
    - Create an extension fun to send messages
    - Create the content intent for the notification to launch this activity
    - Create PendingIntent
    - Set content intent
    - Cancel all notifications

    ---

    - Get an instance of NotificationCompat.Builder to build the notification
    - Set title, text and icon to the Builder
    - Call notify
    - Use the new notification channel

    ---

    - Add style
    - Add style to the Builder
    - Add snooze action

    ---

    - Set priority

    ```kotlin
    // NotificationUtils.kt

    package com.example.android.eggtimernotifications.util

    import android.app.NotificationManager
    import android.app.PendingIntent
    import android.content.Context
    import android.content.Intent
    import android.graphics.BitmapFactory
    import androidx.core.app.NotificationCompat
    import com.example.android.eggtimernotifications.MainActivity
    import com.example.android.eggtimernotifications.R
    import com.example.android.eggtimernotifications.receiver.SnoozeReceiver

    // Notification ID.
    private val NOTIFICATION_ID = 0
    private val REQUEST_CODE = 0
    private val FLAGS = 0

    // Step 1.1 extension function to send messages (GIVEN)
    /**
     * Builds and delivers the notification.
     *
     * @param context, activity context.
     */
    fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
        // Create the content intent for the notification, which launches
        // this activity
        // TODO: Step 1.11 create intent

        // TODO: Step 1.12 create PendingIntent

        // TODO: Step 2.0 add style

        // TODO: Step 2.2 add snooze action

        // TODO: Step 1.2 get an instance of NotificationCompat.Builder
        // Build the notification
        val builder = NotificationCompat.Builder(
            applicationContext,
            applicationContext.getString(R.string.egg_notification_channel_id)
        )

        // TODO: Step 1.8 use the new 'breakfast' notification channel

        // TODO: Step 1.3 set title, text and icon to builder
            .setSmallIcon(R.drawable.cooked_egg)
            .setContentTitle(applicationContext
                .getString(R.string.notification_title))
            .setContentText(messageBody)

        // TODO: Step 1.13 set content intent

            // TODO: Step 2.1 add style to builder

            // TODO: Step 2.3 add snooze action

            // TODO: Step 2.5 set priority

        // TODO: Step 1.4 call notify
        notify(NOTIFICATION_ID, builder.build())
    }

    // TODO: Step 1.14 Cancel all notifications

    ```

- Get an instance of NotificationManager and call *sendNotification*

    EggTimerViewModel

    ```kotlin
    package com.example.android.eggtimernotifications.ui

    import android.app.*
    import android.content.Context
    import android.content.Intent
    import android.os.CountDownTimer
    import android.os.SystemClock
    import androidx.core.app.AlarmManagerCompat
    import androidx.core.content.ContextCompat
    import androidx.lifecycle.*
    import com.example.android.eggtimernotifications.receiver.AlarmReceiver
    import com.example.android.eggtimernotifications.R
    import com.example.android.eggtimernotifications.util.sendNotification
    import kotlinx.coroutines.*

    class EggTimerViewModel(private val app: Application) : AndroidViewModel(app) {

        private val REQUEST_CODE = 0
        private val TRIGGER_TIME = "TRIGGER_AT"

        private val minute: Long = 60_000L
        private val second: Long = 1_000L

        private val timerLengthOptions: IntArray
        private val notifyPendingIntent: PendingIntent

        private val alarmManager = app.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        private var prefs = app.getSharedPreferences(
    						"com.example.android.eggtimernotifications",
    						Context.MODE_PRIVATE
    		)
        private val notifyIntent = Intent(app, AlarmReceiver::class.java)

        private val _timeSelection = MutableLiveData<Int>()
        val timeSelection: LiveData<Int>
            get() = _timeSelection

        private val _elapsedTime = MutableLiveData<Long>()
        val elapsedTime: LiveData<Long>
            get() = _elapsedTime

        private var _alarmOn = MutableLiveData<Boolean>()
        val isAlarmOn: LiveData<Boolean>
            get() = _alarmOn

        private lateinit var timer: CountDownTimer

        init {
            _alarmOn.value = PendingIntent.getBroadcast(
                getApplication(),
                REQUEST_CODE,
                notifyIntent,
                PendingIntent.FLAG_NO_CREATE
            ) != null

            notifyPendingIntent = PendingIntent.getBroadcast(
                getApplication(),
                REQUEST_CODE,
                notifyIntent,
                PendingIntent.FLAG_UPDATE_CURRENT
            )

            timerLengthOptions = app.resources.getIntArray(R.array.minutes_array)

            //If alarm is not null, resume the timer back for this alarm
            if (_alarmOn.value!!) {
                createTimer()
            }

        }

        /**
         * Turns on or off the alarm
         *
         * @param isChecked, alarm status to be set.
         */
        fun setAlarm(isChecked: Boolean) {
            when (isChecked) {
                true -> timeSelection.value?.let { startTimer(it) }
                false -> cancelNotification()
            }
        }

        /**
         * Sets the desired interval for the alarm
         *
         * @param timerLengthSelection, interval timerLengthSelection value.
         */
        fun setTimeSelected(timerLengthSelection: Int) {
            _timeSelection.value = timerLengthSelection
        }

        /**
         * Creates a new alarm, notification and timer
         */
        private fun startTimer(timerLengthSelection: Int) {
            _alarmOn.value?.let {
                if (!it) {
                    _alarmOn.value = true
                    val selectedInterval = when (timerLengthSelection) {
                        0 -> second * 10 //For testing only
                        else ->timerLengthOptions[timerLengthSelection] * minute
                    }
                    val triggerTime = SystemClock.elapsedRealtime() + selectedInterval

                    // Step 1.5 get an instance of NotificationManager and call sendNotification
                    val notificationManager = ContextCompat.getSystemService(                       
                        app,                                                                        
                        NotificationManager::class.java                                             
                    ) as NotificationManager                                                        
                    notificationManager.sendNotification(app.getString(R.string.timer_running), app)
                    
    							  // Step 1.15 call cancel notification

                    AlarmManagerCompat.setExactAndAllowWhileIdle(
                        alarmManager,
                        AlarmManager.ELAPSED_REALTIME_WAKEUP,
                        triggerTime,
                        notifyPendingIntent
                    )

                    viewModelScope.launch {
                        saveTime(triggerTime)
                    }
                }
            }
            createTimer()
        }

        /**
         * Creates a new timer
         */
        private fun createTimer() {
            viewModelScope.launch {
                val triggerTime = loadTime()
                timer = object : CountDownTimer(triggerTime, second) {
                    override fun onTick(millisUntilFinished: Long) {
                        _elapsedTime.value = triggerTime - SystemClock.elapsedRealtime()
                        if (_elapsedTime.value!! <= 0) {
                            resetTimer()
                        }
                    }

                    override fun onFinish() {
                        resetTimer()
                    }
                }
                timer.start()
            }
        }

        /**
         * Cancels the alarm, notification and resets the timer
         */
        private fun cancelNotification() {
            resetTimer()
            alarmManager.cancel(notifyPendingIntent)
        }

        /**
         * Resets the timer on screen and sets alarm value false
         */
        private fun resetTimer() {
            timer.cancel()
            _elapsedTime.value = 0
            _alarmOn.value = false
        }

        private suspend fun saveTime(triggerTime: Long) =
            withContext(Dispatchers.IO) {
                prefs.edit().putLong(TRIGGER_TIME, triggerTime).apply()
            }

        private suspend fun loadTime(): Long =
            withContext(Dispatchers.IO) {
                prefs.getLong(TRIGGER_TIME, 0)
            }
    }
    ```

***Notification Channels***

- Create an extension fun *createChannel (& call it in onCreate)*
    - Create a NotificationChannel instance - pass id, name & importance
    - On the NotificationChannel obj, set the props - enableLights, lightColor, enableVibration, channel description
    - Get an instance of NotificationManager by calling getSystemService
    - Call createNotificationChannel on NotificationManager and pass the NotificationChannel obj.
    - To create the channel, call this *createChannel* ext. fun in the *onCreate* fun.
    - NotificationUtils → build: verify the channel id you previously set is correct

    ---

    - *Pull the status bar and observe the notification title, content and icon are just like you set in the previous steps.*
    - *To verify the newly created channel, close the app and find the app icon. Perform a long click on the app icon and select app info.*

    ```kotlin
    // EggTimerFragment.kt

    package com.example.android.eggtimernotifications.ui

    import android.app.NotificationChannel
    import android.app.NotificationManager
    import android.graphics.Color
    import android.os.Build
    import android.os.Bundle
    import android.util.Log
    import android.view.LayoutInflater
    import android.view.View
    import android.view.ViewGroup
    import android.widget.Toast
    import androidx.databinding.DataBindingUtil
    import androidx.fragment.app.Fragment
    import androidx.lifecycle.ViewModelProvider
    import com.example.android.eggtimernotifications.R
    import com.example.android.eggtimernotifications.databinding.FragmentEggTimerBinding
    import com.google.firebase.messaging.FirebaseMessaging

    class EggTimerFragment : Fragment() {

        private val TOPIC = "breakfast"

        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {

            val binding: FragmentEggTimerBinding = DataBindingUtil.inflate(
                inflater, R.layout.fragment_egg_timer, container, false
            )

            val viewModel = ViewModelProvider(this).get(EggTimerViewModel::class.java)

            binding.eggTimerViewModel = viewModel
            binding.lifecycleOwner = this.viewLifecycleOwner

            // Step 1.7 call create channel
            createChannel(
                getString(R.string.egg_notification_channel_id),
                getString(R.string.egg_notification_channel_name)
            )

            return binding.root
        }

        private fun createChannel(channelId: String, channelName: String) {
            // Step 1.6 START create a channel
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val notificationChannel = NotificationChannel(
                    channelId,
                    channelName,
                    // Change importance
                    NotificationManager.IMPORTANCE_LOW
                )

                notificationChannel.enableLights(true)
                notificationChannel.lightColor = Color.RED
                notificationChannel.enableVibration(true)
                notificationChannel.description = "Time for breakfast!"

                val notificationManager = requireActivity().getSystemService(
                    NotificationManager::class.java
                )
                notificationManager.createNotificationChannel(notificationChannel)

            } else {
                Log.d(TAG, "VERSION.SDK_INT < O")
                Toast.makeText(context, "VERSION.SDK_INT < O", Toast.LENGTH_SHORT).show()
            }

            // Step 1.6 END create a channel

        }

        companion object {
            private const val TAG = "EggTimerFragment"
            fun newInstance() = EggTimerFragment()
        }
    }

    ```

---

### *Add a New Notification*

*AlarmReceiver*

***Add Notifications to Your App***

- Create another notification using AlarmReceiver
    - Create an AlarmReceiver class that inherits BroadcastReceiver
    - Get an instance of NotificationManager by calling getSystemService & call *sendNotification* on it

    ```kotlin
    package com.example.android.eggtimernotifications.receiver

    import android.app.NotificationManager
    import android.content.BroadcastReceiver
    import android.content.Context
    import android.content.Intent
    import android.widget.Toast
    import androidx.core.content.ContextCompat
    import com.example.android.eggtimernotifications.R
    import com.example.android.eggtimernotifications.util.sendNotification

    class AlarmReceiver: BroadcastReceiver() {

        override fun onReceive(context: Context, intent: Intent) {
            // Step 1.10 remove toast (since we're now sending a notification for the same)
            // Toast.makeText(context, context.getText(R.string.eggs_ready), Toast.LENGTH_SHORT).show()

            // TODO: Step 1.9 add call to sendNotification
            val notificationManager = ContextCompat.getSystemService(
                context,
                NotificationManager::class.java
            ) as NotificationManager

    				notificationManager.sendNotification(
                context.getText(R.string.eggs_ready).toString(),
                context
            )

        }

    }
    ```

---

### *Go Back to the App from the Notification using PendingIntent*

*NotificationUtils*

***Add a Content Intent***

- Navigate back to the app on tapping the notification
    - Create an intent
    - Create a pending intent
    - Pass the pending intent to the notification by calling setContentIntent on the NotificationBuilder
    - For the notification to dismiss itself as it takes you to the app when you tap on the it, set setAutoCancel to true

    ```kotlin
    package com.example.android.eggtimernotifications.util

    import android.app.NotificationManager
    import android.app.PendingIntent
    import android.content.Context
    import android.content.Intent
    import android.graphics.BitmapFactory
    import androidx.core.app.NotificationCompat
    import com.example.android.eggtimernotifications.MainActivity
    import com.example.android.eggtimernotifications.R
    import com.example.android.eggtimernotifications.receiver.SnoozeReceiver

    // Notification ID.
    private val NOTIFICATION_ID = 0
    private val REQUEST_CODE = 0
    private val FLAGS = 0

    // Step 1.1 extension function to send messages (GIVEN)
    /**
     * Builds and delivers the notification.
     *
     * @param context, activity context.
     */
    fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
        // Create the content intent for the notification, which launches
        // this activity
        // Step 1.11 create intent
        val contentIntent = Intent(applicationContext, MainActivity::class.java)

        // Step 1.12 create PendingIntent
        val contentPendingIntent = PendingIntent.getActivity(
            applicationContext,
            NOTIFICATION_ID,
            contentIntent,
            PendingIntent.FLAG_UPDATE_CURRENT
        )

        // TODO: Step 2.0 add style

        // TODO: Step 2.2 add snooze action

        // Step 1.2 get an instance of NotificationCompat.Builder
        // Build the notification
        val builder = NotificationCompat.Builder(
            applicationContext,
            applicationContext.getString(R.string.egg_notification_channel_id)
        )

        // TODO: Step 1.8 use the new 'breakfast' notification channel

        // Step 1.3 set title, text and icon to builder
            .setSmallIcon(R.drawable.cooked_egg)
            .setContentTitle(applicationContext
                .getString(R.string.notification_title))
            .setContentText(messageBody)

        // Step 1.13 set content intent
            .setContentIntent(contentPendingIntent)
            .setAutoCancel(true)

            // TODO: Step 2.1 add style to builder

            // TODO: Step 2.3 add snooze action

            // TODO: Step 2.5 set priority

        // Step 1.4 call notify
        notify(NOTIFICATION_ID, builder.build())
    }

    // TODO: Step 1.14 Cancel all notifications
    ```

---

### *Clear the Previous Notifications using cancelAll*

*NotificationUtils, EggTimerViewModel*

***Cancel the Notification***

- Create an extension fun cancelNotifications
    - Add an extension fun on NotificationManager that calls cancelAll

    *NotificationUtils*

    ```kotlin
    funNotificationManager.cancelNotifications() {
        cancelAll()
    }
    ```

- Call the extension fun cancelNotifications in startTimer fun

    *EggTimerViewModel*

    ```kotlin
    notificationManager.cancelNotifications()

    ```

---

### ***Styling Your Notification***

*NotificationUtils*

- Style your Notification in BigPictureStyle
    - Load the image from resources using the BitmapFactory
    - Create a new BigPictureStyle *bigPicStyle* & set your image
    - For the large icon to go away when the notification is expanded, set the bigLargeIcon to null
    - Set the new style *bigPicStyle* to the NotificationBuilder
    - For the image to be displayed as a smaller icon when the notification is collapsed, set your image as setLargeIcon on the builder

    ```kotlin
    package com.example.android.eggtimernotifications.util

    import android.app.NotificationManager
    import android.app.PendingIntent
    import android.content.Context
    import android.content.Intent
    import android.graphics.BitmapFactory
    import androidx.core.app.NotificationCompat
    import com.example.android.eggtimernotifications.MainActivity
    import com.example.android.eggtimernotifications.R
    import com.example.android.eggtimernotifications.receiver.SnoozeReceiver

    // Notification ID.
    private const val NOTIFICATION_ID = 0
    private const val REQUEST_CODE = 0
    private const val FLAGS = 0

    // Step 1.1 extension function to send messages (GIVEN)
    /**
     * Builds and delivers the notification.
     *
     * @param context, activity context.
     */
    fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
        // Create the content intent for the notification, which launches
        // this activity
        // Step 1.11 create intent
        val contentIntent = Intent(applicationContext, MainActivity::class.java)

        // Step 1.12 create PendingIntent
        val contentPendingIntent = PendingIntent.getActivity(
            applicationContext,
            NOTIFICATION_ID,
            contentIntent,
            PendingIntent.FLAG_UPDATE_CURRENT
        )

        // Step 2.0 add style
        val eggImage =  BitmapFactory.decodeResource(
                applicationContext.resources,
                R.drawable.cooked_egg
        )

        val bigPicStyle = NotificationCompat.BigPictureStyle()
                .bigPicture(eggImage)
                .bigLargeIcon(null)

        // TODO: Step 2.2 add snooze action

        // Step 1.2 get an instance of NotificationCompat.Builder
        // Build the notification
        val builder = NotificationCompat.Builder(
            applicationContext,
            applicationContext.getString(R.string.egg_notification_channel_id)
        )

        // TODO: Step 1.8 use the new 'breakfast' notification channel

        // Step 1.3 set title, text and icon to builder
            .setSmallIcon(R.drawable.cooked_egg)
            .setContentTitle(applicationContext
                .getString(R.string.notification_title))
            .setContentText(messageBody)

        // Step 1.13 set content intent
            .setContentIntent(contentPendingIntent)
            .setAutoCancel(true)

        // Step 2.1 add style to builder
                .setStyle(bigPicStyle)
                .setLargeIcon(eggImage)

        // TODO: Step 2.3 add snooze action

        // TODO: Step 2.5 set priority

        // TODO: Step 1.4 call notify
        notify(NOTIFICATION_ID, builder.build())
    }

    // Step 1.14 Cancel all notifications
    fun NotificationManager.cancelNotifications() {
        cancelAll()
    }

    ```

---

### ***Add Snooze Action***

*SnoozeReceiver, NotificationUtils*

- Schedule a new notification & remove the snoozed one
    - Get an instance of NotificationManager

    ```kotlin
    package com.example.android.eggtimernotifications.receiver

    import android.app.AlarmManager
    import android.app.NotificationManager
    import android.app.PendingIntent
    import android.content.BroadcastReceiver
    import android.content.Context
    import android.content.Intent
    import android.os.SystemClock
    import android.text.format.DateUtils
    import androidx.core.app.AlarmManagerCompat
    import androidx.core.content.ContextCompat

    class SnoozeReceiver: BroadcastReceiver() {
        private val REQUEST_CODE = 0

        override fun onReceive(context: Context, intent: Intent) {
            val triggerTime = SystemClock.elapsedRealtime() + DateUtils.MINUTE_IN_MILLIS

            val notifyIntent = Intent(context, AlarmReceiver::class.java)
            val notifyPendingIntent = PendingIntent.getBroadcast(
                context,
                REQUEST_CODE,
                notifyIntent,
                PendingIntent.FLAG_UPDATE_CURRENT
            )

            val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
            AlarmManagerCompat.setExactAndAllowWhileIdle(
                alarmManager,
                AlarmManager.ELAPSED_REALTIME_WAKEUP,
                triggerTime,
                notifyPendingIntent
            )

            val notificationManager = ContextCompat.getSystemService(
                    context,
                    NotificationManager::class.java
            ) as NotificationManager
            notificationManager.cancelAll()
        }

    }
    ```

- Set up a new alarm to post a new notification after 60 secs when the snooze button is tapped by the user by using a PendingIntent
    - Create intent
    - Create a PendingIntent
    - Call the addAction fun on the NotificationBuilder

    ```kotlin
    package com.example.android.eggtimernotifications.util

    import android.app.NotificationManager
    import android.app.PendingIntent
    import android.content.Context
    import android.content.Intent
    import android.graphics.BitmapFactory
    import androidx.core.app.NotificationCompat
    import com.example.android.eggtimernotifications.MainActivity
    import com.example.android.eggtimernotifications.R
    import com.example.android.eggtimernotifications.receiver.SnoozeReceiver

    // Notification ID.
    private const val NOTIFICATION_ID = 0
    private const val REQUEST_CODE = 0
    private const val FLAGS = 0

    // Step 1.1 extension function to send messages (GIVEN)
    /**
     * Builds and delivers the notification.
     *
     * @param context, activity context.
     */
    fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
        // Create the content intent for the notification, which launches
        // this activity
        // Step 1.11 create intent
        val contentIntent = Intent(applicationContext, MainActivity::class.java)

        // Step 1.12 create PendingIntent
        val contentPendingIntent = PendingIntent.getActivity(
            applicationContext,
            NOTIFICATION_ID,
            contentIntent,
            PendingIntent.FLAG_UPDATE_CURRENT
        )

        // Step 2.0 add style
        val eggImage =  BitmapFactory.decodeResource(
                applicationContext.resources,
                R.drawable.cooked_egg
        )

        val bigPicStyle = NotificationCompat.BigPictureStyle()
                .bigPicture(eggImage)
                .bigLargeIcon(null)

        // Step 2.2 add snooze action
        val snoozeIntent = Intent(applicationContext, SnoozeReceiver::class.java)
        val snoozePendingIntent = PendingIntent.getBroadcast(
                applicationContext,
                REQUEST_CODE,
                snoozeIntent,
                FLAGS
        )

        // Step 1.2 get an instance of NotificationCompat.Builder
        // Build the notification
        val builder = NotificationCompat.Builder(
            applicationContext,
            applicationContext.getString(R.string.egg_notification_channel_id)
        )

        // TODO: Step 1.8 use the new 'breakfast' notification channel

        // Step 1.3 set title, text and icon to builder
            .setSmallIcon(R.drawable.cooked_egg)
            .setContentTitle(applicationContext
                .getString(R.string.notification_title))
            .setContentText(messageBody)

        // Step 1.13 set content intent
            .setContentIntent(contentPendingIntent)
            .setAutoCancel(true)

        // Step 2.1 add style to builder
                .setStyle(bigPicStyle)
                .setLargeIcon(eggImage)

        // Step 2.3 add snooze action
                .addAction(
                        R.drawable.egg_icon,
                        applicationContext.getString(R.string.snooze),
                        snoozePendingIntent
                )

        // TODO: Step 2.5 set priority

        // Step 1.4 call notify
        notify(NOTIFICATION_ID, builder.build())
    }

    // Step 1.14 Cancel all notifications
    fun NotificationManager.cancelNotifications() {
        cancelAll()
    }

    ```

---

### *Change Importance*

*EggTimerFragment, NotificationUtils*

- Set the picture

    ```kotlin
    // NotificationUtils()

        // Step 2.0 add style
        val eggImage =  BitmapFactory.decodeResource(
                applicationContext.resources,
                R.drawable.cooked_egg
        )

        val bigPicStyle = NotificationCompat.BigPictureStyle()
                .bigPicture(eggImage)
                .bigLargeIcon(null)

    **********************************************************************************

        val builder = NotificationCompat.Builder(
            applicationContext,
            applicationContext.getString(R.string.egg_notification_channel_id)
        )
    						...
        // Step 2.1 add style to builder
                .setStyle(bigPicStyle)
                .setLargeIcon(eggImage)
    ```

- Change importance from low to high
    - NotificationManager → IMPORTANCE

        ```kotlin
        ...

        class EggTimerFragment : Fragment() {

            ...

            private fun createChannel(channelId: String, channelName: String) {
                // Step 1.6 START create a channel
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    val notificationChannel = NotificationChannel(
                        channelId,
                        channelName,
                        // Change importance
                        NotificationManager.IMPORTANCE_HIGH
                    )

                    notificationChannel.enableLights(true)
                    notificationChannel.lightColor = Color.RED
                    notificationChannel.enableVibration(true)
                    notificationChannel.description = "Time for breakfast!"

                    val notificationManager = requireActivity().getSystemService(
                        NotificationManager::class.java
                    )
                    notificationManager.createNotificationChannel(notificationChannel)

                } else {
                    Log.d(TAG, "VERSION.SDK_INT < O")
                    Toast.makeText(context, "VERSION.SDK_INT < O", Toast.LENGTH_SHORT).show()
                }

                // Step 1.6 END create a channel

            }

            ...
        }
        ```

- Add PRIORITY_HIGH to notification builder object

    *To support devices running API level 25 or lower, you must call setPriority for each notification, using a constant from the NotificationCompat class. To fix this, we're doing the above.*

    ```kotlin
    // *NotificationUtils.kt*

    fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
        ...

        // Step 1.2 get an instance of NotificationCompat.Builder
        // Build the notification
        val builder = NotificationCompat.Builder(
            applicationContext,
            applicationContext.getString(R.string.egg_notification_channel_id)
        )

        ...

        // Step 2.5 set priority
                .setPriority(NotificationCompat.PRIORITY_HIGH)

    	  ...
    }

    ...
    ```

---

### *Notification Badges*

*EggTimerFragment*

- Disable badge
    - Set setShowBadge to false on the NotificationChannel obj.

    ```kotlin
    // *EggTimerFragment.kt*

    private fun createChannel(channelId: String, channelName: String) {
            // Step 1.6 START create a channel
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val notificationChannel = NotificationChannel(
                    channelId,
                    channelName,
                    // Change importance
                    NotificationManager.IMPORTANCE_HIGH
                )
                // Step 2.6 Disable badges for this channel
                        .apply {
                            setShowBadge(false)
                        }
    						...
    				}
    }
    ```