Table of Contents
Understanding Notifications in Android
Notifications are a core part of how Android apps communicate with users outside the app screen. They appear in the status bar, the notification shade, and sometimes on the lock screen. For beginners, the key idea is that your app can show a small message with information or actions even when it is not open.
This chapter focuses on the overall ideas and the basic usage of notifications. The structure introduced here is required to understand channels and action buttons later, so pay close attention to the concepts and the typical workflow of building and showing a notification.
Where Notifications Appear
On an Android device, notifications usually show up as small icons in the status bar at the top of the screen. When the user drags down from the top, the notification shade expands and the full notification is visible. Depending on user settings and device type, notifications can also be visible on the lock screen or as heads up banners that briefly pop up above the current app.
Each notification comes from a specific app and typically has a title, a message text, an icon, and sometimes extra content such as images or action buttons. Users can tap the notification to open the app or a specific screen inside the app.
Core Concepts: Notification Manager and Notification Objects
In Android, notifications are built as objects of the Notification class. To display these objects to the user, you use the system service called NotificationManager. Think of the Notification as a description of what should appear in the shade, and the NotificationManager as the system tool that posts and cancels those notifications.
You usually create and show a notification following this general pattern:
- Obtain a reference to
NotificationManagerCompatorNotificationManager. - Build a
Notificationobject usingNotificationCompat.Builder. - Call
notifywith an integer notification ID and the built notification.
Here is a minimal example that shows the structure, without any advanced features:
val notificationId = 1001
val builder = NotificationCompat.Builder(this, "default_channel_id")
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("New Message")
.setContentText("You have a new message.")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
with(NotificationManagerCompat.from(this)) {
notify(notificationId, builder.build())
}This example uses a channel ID string. The concept of notification channels is covered in a later chapter, so here you only need to understand that the builder must receive a channel ID on newer Android versions.
Essential Notification Components
A basic notification has several important parts that you usually set with the builder. Some of the most common properties are:
setSmallIcon is required for a visible notification. It sets the small icon that appears in the status bar and inside the notification.
setContentTitle sets the main title text of the notification. This is usually a short, clear description such as "New Email" or "Download Complete".
setContentText sets the main message text. It provides more detail about what happened. For longer content, there are styles that allow expanded text, but those are not required for a basic notification.
setPriority controls how important the notification appears on Android versions before channels. You pass constants like NotificationCompat.PRIORITY_DEFAULT or PRIORITY_HIGH. When you learn about channels, you will see that channel importance becomes the main control for this behavior on modern devices.
There are many more configuration options, but these are enough to produce a simple, working notification that appears reliably on a device.
Always set a smallIcon on a notification. Without it, your notification might not show on some devices or versions.
Always provide clear, concise contentTitle and contentText. Confusing or vague text makes users more likely to ignore or disable your notifications.
Notification IDs and Updating or Cancelling
Every time you call notify, you pass an integer ID. This ID identifies the notification inside your app. If you call notify again with the same ID, the existing notification is updated instead of creating a new one. This is useful if you want to show progress or change the text while a task runs.
If you want to remove a notification, you must call cancel with the same ID or cancelAll to remove all notifications from your app.
Example of updating and cancelling with the same ID:
val notificationId = 2002
// Show an initial notification
notificationManager.notify(notificationId, initialNotification)
// Later, update it
notificationManager.notify(notificationId, updatedNotification)
// Finally, cancel it
notificationManager.cancel(notificationId)If you choose random IDs every time, you will get many separate notifications. If you choose stable IDs for certain types of messages, you can keep only the most recent one visible or show a continuous update.
Tapping Notifications and PendingIntent
Most notifications need to perform an action when the user taps them. Typically, this opens an activity such as your MainActivity or a detail screen. To describe this action, you use a PendingIntent. A PendingIntent is a wrapper around an Intent that allows the notification to execute it later, when the user taps.
In a basic notification, you usually set this with setContentIntent. The system then runs that PendingIntent when the user taps the body of the notification.
Here is a simple pattern for adding a tap action:
val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
val pendingIntent = PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_IMMUTABLE
)
val notification = NotificationCompat.Builder(this, "default_channel_id")
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("Welcome")
.setContentText("Tap to open the app.")
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build()
NotificationManagerCompat.from(this).notify(3003, notification)
The setAutoCancel(true) call removes the notification from the shade after the user taps it. This is common for simple notifications that only need to be used once.
When you allow users to open screens from notifications, ensure that the navigation and data are consistent with the rest of your app. Never open a sensitive screen or perform destructive actions without clear user intent.
Basic Behavior and User Expectations
Notifications affect the user experience, so it is important to use them responsibly. Users can block notifications from your app or from specific categories. If you send too many notifications or send irrelevant messages, users are more likely to disable them or uninstall the app.
Basic good practices for notifications include:
Use notifications only when the information is time sensitive or important enough to interrupt the user.
Prefer updating an existing notification when showing the state of an ongoing task, like a download, instead of posting many separate notifications.
Make sure the text is readable and short. Long text can be expanded in advanced styles, but the initial view must be easy to scan quickly.
Respect user choices. If a user disables notifications or opts out of a certain type of message, do not attempt to bypass this behavior.
Background Work and Notifications
Notifications are often triggered from background work, such as services or other background tasks. For example, a message sync service might post a notification when a new chat appears. While the technical details of background tasks belong to other chapters, you should understand that notifications do not require the app activity to be visible. As long as your app code runs in some component, it can ask the notification manager to show a notification.
On modern Android versions, some background work requires using specific APIs or constraints, but the logic for building and posting notifications stays the same. You still build a Notification object and call notify with an ID.
Summary of the Basic Workflow
In everyday development, creating a basic notification usually follows these steps:
Decide what event in your app should trigger the notification.
Create or reuse a channel ID that matches the type of the notification. The detailed setup of channels is covered in the next chapter.
Build a Notification object by setting at least the small icon, title, and text. Optionally add a PendingIntent to react to taps and setAutoCancel(true) if you want the notification to disappear after it is used.
Post the notification with NotificationManagerCompat.from(context).notify(id, notification).
Later, if needed, update the same notification by using the same ID or cancel it when it is no longer relevant.
With this understanding, you are ready to explore notification channels and then learn how to add action buttons that allow users to perform tasks directly from the notification itself.