Setup Android Notification (Prompt to Open App/Activity)

May 9, 2019

Dependencies

dependencies {
    // https://mvnrepository.com/artifact/androidx.appcompat/appcompat
    implementation "androidx.appcompat:appcompat:1.1.0-alpha04"
}

Simple Notification

Create notification channel. Notification Channels are required for Android O (API 26) and above.

What is Notification Channels?. It’s like creating categories of notification (e.g. Daily Reminder, Notifications from Followers, etc.), so user have the option to disable a specific categories of notification (Android Settings -> Notification), rather than disable all notifications from your app.

fun createNotificationChannel(channelId: String) {
    // Create the NotificationChannel, but only on API 26+ because
    // the NotificationChannel class is new and not in the support library
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val name = getString(R.string.notification_channel_name)
        // val descriptionText = getString(R.string.notification_channel_description)
        // https://developer.android.com/training/notify-user/channels.html#importance
        val importance = NotificationManager.IMPORTANCE_DEFAULT
        val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
            // description = descriptionText
        }
        // Register the channel with the system
        val notificationManager: NotificationManager = context!!.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    }
}

val CHANNEL_ID = "daily_reminder"
createNotificationChannel(CHANNEL_ID)

NOTE: You only need to execute createNotificationChannel once per category for the lifetime of your app. Excute multiple times will just overwrite the previous configuration. You can opt to execute once during app startup, and execute it before display notification.

NOTE: The Channel Name should support multiple locales/languages as it is displayed in Android Settings -> Notification.

Create notification with NotificationCompat.Builder.

val builder = NotificationCompat.Builder(context!!, CHANNEL_ID)
    .setSmallIcon(R.drawable.ic_notification_icon)
    .setContentTitle("Title")
    .setContentText("Content")
    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
    .setDefaults(Notification.DEFAULT_SOUND) // to play sounds
    .setColor(ContextCompat.getColor(context!!, R.color.colorPrimary)) // default is Gray
    // optional - support for Do Not Disturb mode
    .setCategory(NotificationCompat.CATEGORY_REMINDER)

NOTE: setSmallIcon is required. You can create using Android Studio -> File -> New -> Image Assets -> Icon Type: Notification Icon.

NOTE: Refer to Notification Priority

NOTE: To play sound when notification is shown, use setDefaults(Notification.DEFAULT_SOUND). Other options include Notification.DEFAULT_VIBRATE, Notification.DEFAULT_LIGHTS. You can include muitple flags using bitwise-or operator: setDefaults(Notification.DEFAULT_SOUND or Notification.DEFAULT_VIBRATE)

NOTE: Refer to Set a system-wide category for setCategory(NotificationCompat.CATEGORY_REMINDER) to better support Do Not Disturb mode.

NOTE: setColor affect small icon and title color shown in the Android pull-down Notification Area (the top Status Bar notification small icon shall remain monochrome)

NOTE: Refer to Create a Group of Notifications

Display Notification

val notificationId = 1
with(NotificationManagerCompat.from(context!!)) {
    // notificationId is a unique int for each notification that you must define
    // using the same notificationId will overwrite/update the previous notification
    // if the previous notification is dismiss, a new notification is created
    notify(notificationId, builder.build())
    // cancel notification by notificationId
    // cancel(notificationId)
}

To update this notification after you’ve issued it, call NotificationManagerCompat.notify() again, passing it a notification with the same ID you used previously. If the previous notification has been dismissed, a new notification is created instead.

You can optionally call setOnlyAlertOnce() so your notification interupts the user (with sound, vibration, or visual clues) only the first time the notification appears and not for later updates. - Source

Notification: Click to launch App/Activity

Configure notification to launch activity upon click/tap.

class MainActivity : AppCompatActivity() {

    companion object {
        const val PARAM_NAVIGATION_ID = "navigation_id"

        fun newInstance(context: Context, navigationId: Int) =  Intent(context, MainActivity::class.java).apply {
            // Intent.FLAG_ACTIVITY_SINGLE_TOP
            // Clear all history, click back will close App
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            putExtra(PARAM_NAVIGATION_ID, navigationId)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)

        navigation.setOnNavigationItemSelectedListener(onNavigationItemSelectedListener)
        val navigationId = intent.getIntExtra(PARAM_NAVIGATION_ID, R.id.navigation_myquote)
        navigation.selectedItemId = navigationId
    }
}
val intent = MainActivity.newInstance(context!!, R.id.navigation_dailyquote)
val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)

NOTE: My MainActivity implement BottomViewNavigation, and I use PARAM_NAVIGATION_ID to indicate which navigation fragment to load.

NOTE: Refer to Start an Activity from a Notification.

val builder = NotificationCompat.Builder(context!!, CHANNEL_ID)
    .setSmallIcon(R.drawable.ic_notification_icon)
    .setContentTitle("Title")
    .setContentText("Content")
    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
    .setDefaults(Notification.DEFAULT_SOUND) // to play sounds
    .setContentIntent(pendingIntent)
    .setAutoCancel(true) // automatically removes the notification when the user taps it

Refer to Create a Notification for more advance usage like

  • Bigger Text: multiline notification
  • Add action button (e.g. Snooze, Reply, etc)
  • Retrieve user input
  • Add progressbar

References:

This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.