Creating custom notifications
August 9, 2021 by Hrithik Sharma
Notifications alert you to many things on your Android device, including incoming messages, new emails, and calendar events. Notifications work slightly differently for each app, but they’re easy to customize.
Starting in Android 8.0 (API level 26), all notifications must be assigned to a channel. For each channel, you can set the visual and auditory behavior that is applied to all notifications in that channel. Then, users can change these settings and decide which notification channels from your app should be intrusive or visible at all.
You can’t change notification behaviour (like channel ID ), after creating a notification channel, but still you can modify channel name and channel description.
You can customize the notifications as your need through setting up different styles , adding action buttons, showing images, playing different sounds while notification arrives, creating custom layouts for notification.
Create a notification channel
To create a notification channel, follow these steps:
- Construct a
NotificationChannel
object with a unique channel ID, a user-visible name, and an importance level. - Optionally, specify the description that the user sees in the system settings with
setDescription()
. - Register the notification channel by passing it to
createNotificationChannel()
.
public static final String channelID = "channelID";
public static final String channelName = "Channel Name";
private NotificationManager mManager;
@RequiresApi(api = Build.VERSION_CODES.O)
private void createChannel() {
NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_HIGH);
getManager().createNotificationChannel(channel);
}
Get Notification manager
public NotificationManager getManager() {
if (mManager == null) {
mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
return mManager;
}
Note: The CHANNEL_ID
should be unique for every notification channel in order to handle this channel in future if we want to modify or delete this channel by using the unique channel_id.
By default, all notifications posted to this channel use the visual and auditory behaviors defined by the importance level from the NotificationManagerCompat
class, such as IMPORTANCE_DEFAULT
and IMPORTANCE_HIGH
.
For more information about importance level:
User-visible importance level | Importance (Android 8.0 and higher) | Priority (Android 7.1 and lower) |
---|---|---|
UrgentMakes a sound and appears as a heads-up notification | ||
IMPORTANCE_HIGH | PRIORITY_HIGH or PRIORITY_MAX | |
HighMakes a sound | IMPORTANCE_DEFAULT | PRIORITY_DEFAULT |
MediumNo sound | IMPORTANCE_LOW | PRIORITY_LOW |
LowNo sound and does not appear in the status bar | IMPORTANCE_MIN | PRIORITY_MIN |
Set the content of the notification
To get started, you need to set the notification’s content and channel using a NotificationCompat.Builder
object.
NotificationCompat.Builder mBuilder= new NotificationCompat.Builder(context.getApplicationContext(), channelID)
.setContentTitle("Title of the notification")
.setContentText("Body of the notification")
.setSmallIcon(R.drawable.ic_launcher_foreground);
-
setContentTitle()
- For title of the notification -
setContentText()
- For additional description of the notification -
setSmallIcon()
- For adding an icon when notification drawer is closedThese are the basic things to show in a notification.
Note: You must have to
setSmallIcon()
otherwise you will get anIllegalArgumentException
when you try to build theNotificationCompat.Builder
This is the basic layout of the notification
Some more methods to customize your notification:
-
setAutoCancel(true)
- To remove notification from notifications drawer after clicking it -
setLargeIcon()
- To add an large icon to notification (visible only in notification drawer) -
setOngoing(true)
- To make notification uncancelable -
setSound(soundUri)
- To set a custom sound to the notificationNotification with large image
How to get
soundUri
?Follow this :
First add a mp3 file to the
raw
resource folder (say, sound.mp3)Then , use the below code to get soundUri
Uri soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE+ "://" +context.getPackageName()+"/"+R.raw.sound);
Note: For API 26+, the sound should be added in
NotificationChannel
alsoUse below code for this:
AudioAttributes audioAttributes = new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setUsage(AudioAttributes.USAGE_ALARM) .build(); channel.setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"+ getApplicationContext().getPackageName() + "/" + R.raw.sound),audioAttributes);
-
setContentIntent(pendingIntent)
- To open desired activity in the application on clicking of the notificationIntent resultIntent = new Intent(context , MainActivity.class); // you can also send data with the intent resultIntent.putExtra("foo",fooObj); // TaskStackbuilder to create a stack of the activities // and add your activity to the top position // according to the parent activities declared in Manifest file TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); stackBuilder.addNextIntentWithParentStack(resultIntent); // PendingIntent to use in the setContentIntent() method PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(4,PendingIntent.FLAG_UPDATE_CURRENT); builder.setContentIntent(resultPendingIntent);
-
setStyle()
- To set your desired style to the notification (e.g., BigPictureStyle , BigTextStyle, MessagingStyle etc. )
Create custom styles of the notification
We are going to use setStyle()
method of NotificationCompat.Builder
to set different styles to the notification.
Add a large block of text
Apply NotificationCompat.BigTextStyle()
to display a large block of text in notification,
NotificationCompat.Builder mBuilder= new NotificationCompat.Builder(context.getApplicationContext(), channelID)
.setStyle(new NotificationCompat.BigTextStyle().bigText(bigBody))
.setContentTitle(title)
.setContentText("Click this notification's header to see larger text.")
.setSmallIcon(R.drawable.ic_launcher_foreground);
Upper one - Collapsed
Lower one - Expanded
Add a large expandable image
Apply NotificationCompat.BigPictureStyle()
to show a large expandable image,
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.android1);
NotificationCompat.Builder mBuilder= new NotificationCompat.Builder(context.getApplicationContext(), channelID)
.setLargeIcon(bitmap)
.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(bitmap)
.bigLargeIcon(null))
.setContentTitle("Expandable Image")
.setContentText("Click this notification's header to see expanded image")
.setSmallIcon(R.drawable.ic_launcher_foreground);
setLargeIcon()
sets the image as a thumbnail when the notification is collapsed , that’s why set bigLargeIcon(null)
so that the largeIcon (thumbnail) goes away when the notification expands.
Inbox Styled Notification
Apply NotificationCompat.InboxStyle()
to make your notification inbox styled.
NotificationCompat.Builder mBuilder= new NotificationCompat.Builder(context.getApplicationContext(), channelID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Inbox style")
.setContentText("This is the inbox styled notification")
.setStyle(new NotificationCompat.InboxStyle()
.addLine("Inbox Line 1")
.addLine("Inbox Line 2"));
To add more lines to the notification call addLine()
.
You should call addLine() more than 6 times because more than 6 times will show only first 6 lines.
Conversational Notification
Apply NotificationCompat.MessagingStyle()
to your notification style and you will get notification with sequential messaging layout.
NotificationCompat.MessagingStyle.Message message1 = new NotificationCompat.MessagingStyle.Message("Hey buddy, what's up",
1627906259,
"Android");
NotificationCompat.MessagingStyle.Message message2 = new NotificationCompat.MessagingStyle.Message("I am fine, what about you?",
1627906326,
"You");
NotificationCompat.MessagingStyle.Message message3 = new NotificationCompat.MessagingStyle.Message("Good, \uD83D\uDE42\uD83D\uDE42",
1627909912,
"Android");
NotificationCompat.Builder mBuilder= new NotificationCompat.Builder(context.getApplicationContext(), channelID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setStyle(new NotificationCompat.MessagingStyle("User Dsplay Name")
.addMessage(message1)
.addMessage(message2)
.addMessage(message3));
NotificationCompat.MessagingStyle.Message
Parameters:
-
text (1st parameter) - The message of the sender
-
timestamp (2nd parameter) - Time of the message sent
-
sender (3rd parameter) - Sender of the message
Note: Messages in the notification will be sorted according to the timestamp of the message
Upper one - Collapsed
Lower one - Expanded
Create custom layout for notification
-
First create a layout for the notification
Remember that , constraint layout is not allowed for custom notification’s layout
notification_layout.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" > <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@color/black"/> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="12sp" android:textColor="@color/black" android:layout_below="@id/title"/> </RelativeLayout>
-
Instantiating a RemoteViews object and set it to the notification,
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.notification_layout); remoteViews.setTextViewText(R.id.title,"Custom notification title"); remoteViews.setTextViewText(R.id.text,"Text for the notification"); NotificationCompat.Builder mBuilder= new NotificationCompat.Builder(context.getApplicationContext(), channelID) .setSmallIcon(R.drawable.ic_launcher_foreground) .setStyle(new NotificationCompat.DecoratedCustomViewStyle()) .setCustomContentView(remoteViews);
Show notification
To show the notification call mManager.notify()
and pass a unique id of the notification and also the Notification which can be get by mBuilder.build()
getManager().notify(UNIQUE_NOTIFICATION_ID,mBuilder.build());
Remember that notificationId should be unique int and will require when you want to update or remove the notification.
getManager()
is defined at top of the article
You can see the source code here - CustomNotification
Feedback and suggestions are welcome.
I hope you find it useful or at least it gives you some fresh ideas.
Thanks for reading 🙌🏼
Happy coding🔥🔥😀😀