Overview
Android devices use notifications to inform users about events, updates, or background tasks. The NotificationCompat API (from AndroidX) provides backward-compatible support for creating and displaying notifications across different API levels.
This document explains how to create and display notifications using NotificationCompat, including basic notifications, notification channels (required on Android 8.0+), and actionable notifications.
Notification Architecture in Android
Notifications are delivered through the NotificationManager, and the UI is constructed via Notification objects. Since Android 8.0 (API level 26), notifications must be associated with a Notification Channel.
Key components:
- NotificationManager: System service that displays notifications
- Notification Channel: Required on Android 8.0+ to organize notifications
- NotificationCompat.Builder: Builds notifications with compatibility support
Using AndroidX’s NotificationCompat ensures consistent behavior across all supported API levels.
Setting Up a Notification Channel
A notification channel must be created before sending notifications on Android 8.0 and higher.
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String channelId = "default_channel_id";
CharSequence channelName = "Default Notifications";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
channel.setDescription("General notifications");
notificationManager.createNotificationChannel(channel);
}
Notification channels allow the user to control preferences, such as sound and vibration, for groups of related notifications.
Creating a Basic Notification
Using NotificationCompat.Builder, you can create a simple notification with title, message, and icon.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "default_channel_id")
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("Sample Notification")
.setContentText("This is an example notification using NotificationCompat.")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
// Each notification should use a unique ID
int notificationId = 101;
notificationManager.notify(notificationId, builder.build());
This creates a basic notification with a title, text, icon, and default priority. setAutoCancel(true) ensures the notification dismisses when the user taps it.
Adding an Intent to Open an Activity
To respond when a user taps the notification, use a PendingIntent.
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "default_channel_id")
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("New Message")
.setContentText("Tap to open the app.")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.setAutoCancel(true);
The PendingIntent wraps the intent that launches the target activity when the user interacts with the notification.
Adding Action Buttons
Notifications can include buttons for additional actions (for example, reply or delete).
Intent replyIntent = new Intent(this, ReplyReceiver.class);
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(this, 0, replyIntent, 0);
builder.addAction(new NotificationCompat.Action(
R.drawable.ic_reply, "Reply", replyPendingIntent
));
Action buttons enhance interaction without requiring the user to open the app.
Setting Priority and Importance
For Android versions below 8.0, notifications use priority to control how they appear:
PRIORITY_HIGH— intrusive alertsPRIORITY_DEFAULT— standard notificationsPRIORITY_LOW— minimal interruption
On Android 8.0 and above, use importance when creating notification channels, since priority is superseded by channel importance settings.
Displaying Progress in Notifications
To display ongoing work (for example, a file download), use a progress bar in the notification:
builder.setProgress(100, 0, false);
notificationManager.notify(notificationId, builder.build());
for (int progress = 1; progress <= 100; progress++) {
builder.setProgress(100, progress, false);
notificationManager.notify(notificationId, builder.build());
try {
Thread.sleep(50);
} catch (InterruptedException ignored) {}
}
builder.setProgress(0, 0, false)
.setContentText("Download complete");
notificationManager.notify(notificationId, builder.build());
Use this pattern for determinate progress notifications.
Best Practices
1. Create Channels Strategically
Group similar notifications (for example, messages, downloads, alerts) under separate channels so users can tailor preferences.
2. Use Notification IDs Carefully
Use unique IDs for different notifications. If you want to update a notification (for example, progress), reuse the same ID.
3. Respect User Settings
Once notification channels are created, users can modify importance, sound, and visibility. Your app should not override these settings programmatically.
4. Avoid Excessive Alerts
Use appropriate priorities and avoid notifying users too frequently unless necessary.


