How to implement notifications in Android Lollipop

Notifications are messages that can be displayed to users outside of an application's UI in an Android phone or tablet. Android displays an icon in the status bar to indicate a notification. Swiping down from the status bar reveals the notification drawer, where the notifications are displayed, usually with an icon, a title and content message.

Android Lollipop introduced new types of notifications. There are now heads-up notifications which appear as little pop-up notifications at the top of the screen. They are identical to the notifications in the notification drawer. Heads-Up notifications do not interrupt user activity. Another lollipop change includes notifications being displayed on the lock screen while the device remains locked. This can be customised by app developers to show either the full notification content, partial content, or not at all.

In this tutorial, we discuss how to create these types of notifications on Android L. Even if you have never coded a notification before, we will show how to create a notification using the compatibility library that is portable across different Android versions.

Preparation

Notifications are a vital part of the Android user experience. As such, they have their own design guidelines.

At the very least, a notification must contain:

  • A small icon which is displayed on the notification bar
  • A title
  • Content text

Our sample application is a simple activity with different sections that generate different types of notifications.

Basic Notification

To create the most basic notification, place the following code at the point you want to generate the notification. In our case, this would be in the OnClickListener of each button.

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context
                .NOTIFICATION_SERVICE);

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_launcher_notification)
                .setContentTitle("Simple Notification")
                .setContentText("This is a normal notification.");

        notificationManager.notify(BASIC_NOTIFICATION_ID, notificationBuilder.build());

We use NotificationCompat.Builder which is available through the app compat v4 library. The builder helps us build a notification with the appropriate icon, title and content text. Then we call NotificationManager.notify(), with an integer notificationID, and the notification built by calling build() on the NotificationCompat.Builder object.

The notificationID is important. Use different notificationIDs when you want to show different notifications. If there is already an available notification with the same ID, it would be updated.

LockScreen Notifications

There are three types of lock screen notifications.

Public notifications show the full contents of the notification. The value is NotificationCompat.VISIBILITY_PUBLIC.

Private notifications show the icon and app name, but not the notification content. This can be customised to show alternate text. It is also the default. Its value is NotificationCompat.VISIBILITY_PRIVATE.

Secret notifications are never shown on the lock screen. Its value is NotificationCompat.VISIBILITY_SECRET.

To specify public notifications, add the appropriate value to the setVisibility method of your notificationBuilder.

notificationBuilder.setVisibility(NotificationCompat.VISIBILITY_SECRET);

Heads-Up Notifications

To create a heads-up notification, one of the following conditions must be met.

  • The notification has high priority, and uses ringtones or vibrations.
  • The app uses fullScreenIntent.

With the above knowledge, we create a notification, setting it to vibrate, and setting the priority to PRIORITY_MAX.

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_launcher_notification)
                .setPriority(NotificationCompat.PRIORITY_MAX)
                .setVibrate(new long[] {1, 1, 1})
                .setCategory(NotificationCompat.CATEGORY_MESSAGE)
                .setContentTitle("Simple Heads-Up Notification")
                .setContentText("This is a heads-up notification.");

Alternatively, we can set a fullScreenIntent on the NotificationCompat.Builder object.

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_launcher_notification)
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setCategory(NotificationCompat.CATEGORY_MESSAGE)
                .setContentTitle("Simple Heads-Up Notification")
                .setContentText("This is a heads-up notification.");

            Intent push = new Intent();
            push.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            push.setClass(this, MainActivity.class);

            PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
                    push, PendingIntent.FLAG_CANCEL_CURRENT);
            notificationBuilder
                    .setContentText("A Heads-Up notification for Lollipop and above")
                    .setFullScreenIntent(fullScreenPendingIntent, true);

        notificationManager.notify(HEADS_UP_NOTIFICATION_ID, notificationBuilder.build());

Custom Notifications

There are situations where the default notifications are not sufficient, and you want to design your own custom notification. In that case, you have two options.

You can use the NotificationCompat.Style which provides three possible styles: the InboxStyle, the BigPictureStyle, and the BigTextStyle. To use any of these, call the setStyle() method on your NotificationCompat.Builder object, with the desired style. For example:

        NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle()
                .addLine("First line")
                .addLine("Second line")
                .setBigContentTitle("Multiple Content")
                .setSummaryText("+2 Messages");

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_launcher_notification)
                .setContentTitle("Sample Title")
                .setContentText("Sample Text")
                .setStyle(inboxStyle);

Alternatively, you can define a RemoteView.

To use a RemoteView, we design the layout in xml. Name it anything you like. We name ours custom_notification.xml, saved in the layouts directory. One very important point to note is that RemoteViews do not support all android layouts and widgets. The supported layouts are FrameLayout, LinearLayout, RelativeLayout and GridLayout, while the supported widgets are AnalogClock, Button, Chronometer, ImageButton, ImageView, ProgressBar, TextView, ViewFlipper, ListView, GridView, StackView, and AdapterViewFlipper. Attempting to use any other classes will result in runtime errors.

Also, note the style used for the TextView (@android:style/TextAppearance.StatusBar.EventContent). This ensures that the TextView would be visible on both devices with dark background and white text, and white background and dark text.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="8dp"
    android:paddingRight="8dp">

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="This is a custom notification with RemoteView"
        android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent"
        android:paddingRight="8dp"/>

        <ImageView
            android:id="@+id/secondTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"
            android:paddingLeft="8dp"
            android:src="@drawable/ic_contact_picture"/>

</LinearLayout>

Then we create a RemoteView object that references our layout, and instruct the NotificationCompat.Builder to use the RemoteView with setContent().

        RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.custom_notification);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setContent(remoteViews);

        notificationManager.notify(CUSTOM_NOTIFICATION_ID, notificationBuilder.build());

Be sure to read the notification API and design guidelines. As usual, you can download, modify and/or use the complete source, available on github.

Subscribe to Xmodulo

Do you want to receive Linux FAQs, detailed tutorials and tips published at Xmodulo? Enter your email address below, and we will deliver our Linux posts straight to your email box, for free. Delivery powered by Google Feedburner.


Support Xmodulo

Did you find this tutorial helpful? Then please be generous and support Xmodulo!

The following two tabs change content below.

Obaro Ogbo

Obaro Ogbo is a software developer, who's always on the hunt for easy ways to solve complex problems. He enjoys the freedom offered by UNIX based systems (Linux and Android), and can be spotted peering at a screen creating, studying or enjoying different types of computer programs. He's currently exploring mobile app and game development. When away from technology, he's most probably sleeping or playing basketball.

One thought on “How to implement notifications in Android Lollipop

  1. java.lang.IllegalArgumentException: Invalid notification (no valid small icon)

    If I add icon the shown notification is empty

Leave a comment

Your email address will not be published. Required fields are marked *