Notification and it’s types in Android

Abhishek Pathak
6 min readDec 22, 2022

--

Notifications are one of the fastest and easiest ways to add more interactivity and engagement to your application. Android Notification provides short, timely information about the action happened in the application, even it is not running. The notification displays the icon, title and some amount of the content text.

In this article you are going to learn basics of Android notifications and it’s properties as well as their implementation concepts.

Notification Properties

The properties of Android notification are set using NotificationCompat.Builder object. Some of the notification properties are mention below:

  1. Small icon: From above screenshot, small icon will be set by setSmallIcon()
  2. App Name: This is provided by the system. For example here app name is messages.
  3. Timestamp: This is provided by the system but you can override it with setWhen() or hide it with setShowWhen(false).
  4. Large icon: This is optional (usually used only for contact photos; do not use it for your app icon) and set with setLargeIcon().
  5. Title: This is optional and set with setContentTitle().
  6. Text: This is optional and set with setContentText().

Types of Notifications in Android

Notification stages

Notification Simple Implementation

Okay so here I am ready to demonstrate a simple app implementation to show case notifications with all of it’s types.

Step 1 : Notification channel

Channels were introduced in Oreo, and allow users to select which notifications their applications can show them. As application developers we should our notifications based on their topic. If an application uses only one channel for all of its notifications, the user would not be able to select which notifications they want to see and if they blocked one channel, they would no longer get notifications from the application.

Let’s understand the Notification importance as sub topic under notification channel

Importance of notification category wise according to the use-case as mentioned below and it is captured from NotificationManager API documentation.

/**
* Min notification importance: only shows in the shade, below the fold. This should
* not be used with {@link Service#startForeground(int, Notification) Service.startForeground}
* since a foreground service is supposed to be something the user cares about so it does
* not make semantic sense to mark its notification as minimum importance. If you do this
* as of Android version {@link android.os.Build.VERSION_CODES#O}, the system will show
* a higher-priority notification about your app running in the background.
*/
public static final int IMPORTANCE_MIN = 1;

/**
* Low notification importance: Shows in the shade, and potentially in the status bar
* (see {@link #shouldHideSilentStatusBarIcons()}), but is not audibly intrusive.
*/
public static final int IMPORTANCE_LOW = 2;

/**
* Default notification importance: shows everywhere, makes noise, but does not visually
* intrude.
*/
public static final int IMPORTANCE_DEFAULT = 3;

/**
* Higher notification importance: shows everywhere, makes noise and peeks. May use full screen
* intents.
*/
public static final int IMPORTANCE_HIGH = 4;

Coming to Notification channel code snippet

/*  Create the NotificationChannel, but only on API 26+ because the 
NotificationChannel class is new and not in the support library

About Notification Importance - This controls how interruptive
notifications posted to this channel are.
*/
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val importance = NotificationManager.IMPORTANCE_HIGH
val channel = NotificationChannel(
channelId,
description,
NotificationManager.IMPORTANCE_DEFAULT
)
channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(channel)
}
}

Step 2: Make a Pending Intent

/*
* ABOUT PENDING INTENT
A PendingIntent is a token that you give to a foreign application
which allows the foreign application to use your application's permissions
to execute a predefined piece of code
*
*/
private fun setPendingIntent(context: Context) {
val intent = Intent(context, HomeActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
context,
0,
intent,
PendingIntent.FLAG_IMMUTABLE
)
}

Step 3: Implement Notification Builder

private fun showNotification(context: Context) {
val builder = NotificationCompat.Builder(context, "sample")
val content = context.getString(R.string.content_of_notification)
val title = context.getString(R.string.title_of_app)
builder.setContentTitle(title)
.setContentText(content)
.setSmallIcon(R.drawable.ic_baseline_local_phone_24)
.setColor(ContextCompat.getColor(context, R.color.purple_500))
.setOngoing(true)
.setStyle(
NotificationCompat.BigTextStyle().bigText(content)
.setBigContentTitle(title)
)
.setAutoCancel(false)

Now let’s create types of Notifications

Type 1: Simple Notification

private fun makeSimpleNotification() {
getNotificationChannel()

notificationBuilder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Notification.Builder(this, channelId)
.setContentTitle(getString(R.string.your_title))
.setContentText(getString(R.string.your_body))
.setSmallIcon(R.mipmap.app_icon)
.setContentIntent(setPendingIntent(this))
} else {
Notification.Builder(this)
.setContentTitle(getString(R.string.your_title))
.setContentText(getString(R.string.your_body))
.setSmallIcon(R.mipmap.app_icon)
.setContentIntent(setPendingIntent(this))
}
notificationManager.notify(1, notificationBuilder.build())
}

Type 2: Big Picture Style Notification

private fun makeBigPictureNotification() {
getNotificationChannel()

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val style = NotificationCompat.BigPictureStyle()
style.bigPicture(BitmapFactory.decodeResource(resources, R.drawable.profile)).build()

val notificationBuilder = NotificationCompat.Builder(this, channelId)
.setContentTitle(getString(R.string.your_title))
.setContentText(getString(R.string.your_body))
.setSmallIcon(R.drawable.ic_launcher_background)
.setStyle(style)
.setContentIntent(setPendingIntent(this))
notificationManager.notify(1, notificationBuilder.build())
}
}

Type 3: Inbox Style Notification

private fun makeInboxStyleNotification() {
getNotificationChannel()
val style = Notification.InboxStyle()
style.apply {
addLine("Message 1 hey")
addLine("Message 2 Hi")
addLine("Message 3 how are you?")
addLine("Message 4 I am good")
addLine("Message 5 you are bad")
addLine("Message 6 okay")
addLine("Message 7 fine")
addLine("Message 8 let's go")
setSummaryText("+10 more items..")
}
notificationBuilder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Notification.Builder(this, channelId)
.setContentTitle(getString(R.string.your_title))
.setContentText(getString(R.string.your_body))
.setSmallIcon(R.drawable.ic_launcher_background)
.setStyle(style)
.setContentIntent(setPendingIntent(this))
} else {
Notification.Builder(this)
.setContentTitle(getString(R.string.your_title))
.setContentText(getString(R.string.your_body))
.setStyle(style)
.setContentIntent(setPendingIntent(this))
}
notificationManager.notify(1, notificationBuilder.build())
}

Here is the full source code

class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var notificationChannel: NotificationChannel
private lateinit var notificationManager: NotificationManager
private lateinit var notificationBuilder: Notification.Builder
private val channelId = "ChannelId"

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initViews()
}

private fun initViews() {
binding.apply {
btnSimpleNotification.setOnClickListener {
makeSimpleNotification()
}
btnInboxStyleNotification.setOnClickListener {
makeInboxStyleNotification()
}
btnBigPictureNotification.setOnClickListener {
makeBigPictureNotification()
}
}
}

private fun makeSimpleNotification() {
getNotificationChannel()

notificationBuilder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Notification.Builder(this, channelId)
.setContentTitle(getString(R.string.your_title))
.setContentText(getString(R.string.your_body))
.setSmallIcon(R.mipmap.app_icon)
.setContentIntent(setPendingIntent(this))
} else {
Notification.Builder(this)
.setContentTitle(getString(R.string.your_title))
.setContentText(getString(R.string.your_body))
.setSmallIcon(R.mipmap.app_icon)
.setContentIntent(setPendingIntent(this))
}
notificationManager.notify(1, notificationBuilder.build())
}

private fun makeInboxStyleNotification() {
getNotificationChannel()
val style = Notification.InboxStyle()
style.apply {
addLine("Message 1 hey")
addLine("Message 2 Hi")
addLine("Message 3 how are you?")
addLine("Message 4 I am good")
addLine("Message 5 you are bad")
addLine("Message 6 okay")
addLine("Message 7 fine")
addLine("Message 8 let's go")
setSummaryText("+10 more items..")
}
notificationBuilder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Notification.Builder(this, channelId)
.setContentTitle(getString(R.string.your_title))
.setContentText(getString(R.string.your_body))
.setSmallIcon(R.drawable.ic_launcher_background)
.setStyle(style)
.setContentIntent(setPendingIntent(this))
} else {
Notification.Builder(this)
.setContentTitle(getString(R.string.your_title))
.setContentText(getString(R.string.your_body))
.setStyle(style)
.setContentIntent(setPendingIntent(this))
}
notificationManager.notify(1, notificationBuilder.build())
}

private fun makeBigPictureNotification() {
getNotificationChannel()

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val style = NotificationCompat.BigPictureStyle()
style.bigPicture(BitmapFactory.decodeResource(resources, R.drawable.profile)).build()

val notificationBuilder = NotificationCompat.Builder(this, channelId)
.setContentTitle(getString(R.string.your_title))
.setContentText(getString(R.string.your_body))
.setSmallIcon(R.drawable.ic_launcher_background)
.setStyle(style)
.setContentIntent(setPendingIntent(this))
notificationManager.notify(1, notificationBuilder.build())
}
}

/*
* ABOUT NOTIFICATION CHANNEL
Channels were introduced in Oreo, and allow users to select which notifications their applications
can show them. As application developers we should our notifications based on their topic. If
an application uses only one channel for all of its notifications,the user would not be able
to select which notifications they want to see and if they blocked one channel,
they would no longer get notifications from the application.
*
*/
private fun getNotificationChannel() {
notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notificationChannel = NotificationChannel(
channelId,
getString(R.string.description_of_your_channel),
NotificationManager.IMPORTANCE_HIGH
).also {
it.enableLights(true)
it.enableVibration(true)
}
notificationManager.createNotificationChannel(notificationChannel)
}
}

/*
* ABOUT PENDING INTENT
A PendingIntent is a token that you give to a foreign application
which allows the foreign application to use your application's permissions
to execute a predefined piece of code
*
*/
private fun setPendingIntent(context: Context): PendingIntent {
val intent = Intent(context, HomeActivity::class.java)
return PendingIntent.getActivity(
context,
0,
intent,
PendingIntent.FLAG_IMMUTABLE
)
}
}

You can get the full source code from GITHUB

Thanks for reading this article. Be sure to click 👏 below to applause this article if you found it helpful. It means a lot to me.

--

--