saloni33 / android_documentation

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Notifications In Android

Notification is a message that you can display to the user outside your app’s UI. Android Notifications provide short and precise information about the action that happened in your app. The notification displays the icon, title, and some amount of the content text.

Appearances on a device

Notifications could be of various formats and designs depending upon the developer such as an icon in the status bar, a more detailed entry in the notification drawer, as a badge on the app's icon.

  1. Status Bar Notification - When you issue a notification, it first appears as an icon in the status bar. It appears in the same layout as the current time, battery percentage
  2. Notification drawer Notification - It appears in the drop-down menu. Users can swipe down on the status bar to open the notification drawer, where they can view more details and take action with the notification.
  3. Heads-Up Notification - Beginning with Android 5.0, notifications can briefly appear in a floating window called a heads-up notification. It appears on the overlay screen, ex: Whatsapp notification, OTP messages
  4. Lock-Screen Notification - It appears on the lock screen. Beginning with Android 5.0, notifications can appear on the lock screen.
  5. App icon badge - In supported launchers on devices running Android 8.0 (API level 26) and higher, app icons indicate new notifications with a colored "badge" (also known as a "notification dot") on the corresponding app launcher icon.

Create a Notification

The design of notification is quite simple, it contains an icon, title, some brief about the message(optional), and click. An example of the same is shown below:

  1. Small Icon - This can be set using setSmallIcon().
  2. App Name - This is provided by the app itself.
  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().

Using Notification Channels

Notification Channels provide you with the ability to group the notifications that our application sends into manageable groups. Starting in Android 8.0 (API level 26), all notifications must be assigned to a channel or they will not appear.

By managing different channels, users will be able to disable specific notifications (instead of disabling all notifications), and users can control the visual and auditory options for each channel.

One app can have multiple notification channels—a separate channel for each type of notification the app issues. An app can also create notification channels in response to choices made by users of your app.

For example, have a look at the Clock app that is installed with Android (tap Settings > App Notifications > Notifications and select Clock from the list).

How to Create a Notification

Below are the steps which are required for creating a notification in android -

  1. Add the support Library
    Many projects made with Android Studio already include the necessary dependencies to use NotificationCompat, if not you should add the following dependencies in build.gradle file:

      val core_version = "1.6.0"
      dependencies {
          implementation "androidx.core:core:$core_version"
      }
    
    
  2. Create a basic notification
    A basic notification contains an icon, title, a short description. Below are some steps, from which you can learn how to create a simple notification that a user can click on.

  • Set notification content
    First of all, we need to set the notification content and channel using a NotificationCompat.Builder object.
    A small icon can be set using setSmallIcon(), title by setContentTitle(), text of the notification by setContentText(), and notification priority by using setPriority(). If you want a notification to be longer, you can use setStyle() for the same.
    Example code for Java is -

    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle(textTitle)
            .setContentText(textContent)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT);
    
  • Create a channel and set the importance
    For the version Android 8.0 and higher, you need to register the notification channel of your app with the system by passing an instance of NotificationChannel to createNotificationChannel().
    To create a notification channel, you need to follow the following steps- Construct a NotificationChannel object which requires unique channel_id and channel_name strings. The Importance argument is an int that specifies the level of interruption by the notification. . It can be one of the following values:

    Importance (Android 8.0 and higher) Description
    IMPORTANCE_DEFAULT Shows up in the system tray. Makes sound. Doesn’t visually pop up.
    IMPORTANCE_HIGH Visually pops up too.
    IMPORTANCE_LOW Shows in the tray. No pop-up. No sound.
    IMPORTANCE_NONE Doesn’t show up. Kind of blocked notifications.

        The sample code for creating a channel is -

  private void createNotificationChannel() {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
             CharSequence name = getString(R.string.channel_name);
             String description = getString(R.string.channel_description);
             int importance = NotificationManager.IMPORTANCE_DEFAULT;
             NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
             channel.setDescription(description);
             // Register the channel with the system; you can't change the importance
             // or other notification behaviors after this
             NotificationManager notificationManager = getSystemService(NotificationManager.class);
             notificationManager.createNotificationChannel(channel);
        }
}
  • Set the notification's tap action
    When a user taps on any notification, it should respond by opening an activity in the app which corresponds to that particular notification. For the same, you need to specify a content intent defined with a PendingIntent object and pass it to setContentIntent().
    The following sample code shows how to create a basic intent to open an activity when the user taps the notification:

    // Create an explicit intent for an Activity in your app
    Intent intent = new Intent(this, AlertDetails.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, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Hello World!")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            // Set the intent that will fire when the user taps the notification
            .setContentIntent(pendingIntent)
            .setAutoCancel(true);
    
  • Show the notification
    To make the notification appear on the screen, we need to call NotificationManagerCompat.notify(), passing it a unique ID for the notification and the result of NotificationCompat.Builder.build().

    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
    // notificationId is a unique int for each notification that you must define
    notificationManager.notify(notificationId, builder.build());
    
  1. Add action buttons
    When we receive a notification, there is only a single action available -tapping on the notification. However, Action Buttons allow more than one action to be taken on a notification, allowing for greater interactivity within notifications, like snooze or dismiss, etc.

    To add an action button, pass a PendingIntent to the addAction() method. This is just like setting up the notification's default tap action, except instead of launching an activity.

  Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class);
  snoozeIntent.setAction(ACTION_SNOOZE);
  snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0);
  PendingIntent snoozePendingIntent = PendingIntent.getBroadcast(this, 0, snoozeIntent, 0);
  NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
         .setSmallIcon(R.drawable.notification_icon)
         .setContentTitle("My notification")
         .setContentText("Hello World!")
         .setPriority(NotificationCompat.PRIORITY_DEFAULT)
         .setContentIntent(pendingIntent)
         .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                 snoozePendingIntent);

    Above is the code that shows how to send a broadcast to a specific receiver.

  1. Add a direct reply action
    The direct reply action allows the user to directly enter text into the notification. Such features are commonly seen in messaging applications like WhatsApp, Facebook messenger, etc.
    The direct reply action opens a text input for the user to type the reply message. When the user finishes, the system attaches the response to the intent you had specified for the notification action and sends the intent to your app.

  • Add the reply button Steps to create notification action with a direct reply

      // Key for the string that's delivered in the action's intent.
    private static final String KEY_TEXT_REPLY = "key_text_reply";
    String replyLabel = getResources().getString(R.string.reply_label);
    RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
            .setLabel(replyLabel)
            .build();
    
      // Build a PendingIntent for the reply action to trigger.
      PendingIntent replyPendingIntent =
          PendingIntent.getBroadcast(getApplicationContext(),
                  conversation.getConversationId(),
                  getMessageReplyIntent(conversation.getConversationId()),
                  PendingIntent.FLAG_UPDATE_CURRENT);
    
      // Create the reply action and add the remote input.
      NotificationCompat.Action action =
           new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon,
                   getString(R.string.label), replyPendingIntent)
                   .addRemoteInput(remoteInput)
                   .build();
    
    • Apply the action to notification and issue the notification.
      // Build the notification and add the action.
      Notification newMessageNotification = new Notification.Builder(context, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_message)
            .setContentTitle(getString(R.string.title))
            .setContentText(getString(R.string.content))
            .addAction(action)
            .build();
      // Issue the notification.
      NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
      notificationManager.notify(notificationId, newMessageNotification);
    
  • Retrieve user input from the reply
    To receive the input from the notification's reply UI which the user has entered, you need to call RemoteInput.getResultsFromIntent() ,passing it the Intent received by your BroadcastReceiver.

      private CharSequence getMessageText(Intent intent) {
       Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
       if (remoteInput != null) {
           return remoteInput.getCharSequence(KEY_TEXT_REPLY);
       }
       return null;
    }
    

        After this step, you need to update the notification, so as to hide the direct reply UI, by calling
        NotificationManagerCompat.notify() with the same ID and tag (if used).

  // Build a new notification, which informs the user that the system
  // handled their interaction with the previous notification.
  Notification repliedNotification = new Notification.Builder(context, CHANNEL_ID)
         .setSmallIcon(R.drawable.ic_message)
         .setContentText(getString(R.string.replied))
         .build();
 // Issue the new notification.
 NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
 notificationManager.notify(notificationId, repliedNotification);

       When working with this new notification, use the context that's passed to the receiver's onReceive() method. You
       should also append the reply to the bottom of the notification by calling setRemoteInputHistory().

  • Add a progress bar
    You can also include a progress bar in a notification to show the progress of the ongoing operation. Example -

The progress bar supports two modes to represent progress: determinate, and indeterminate. To set the determinate form of the progress you can use setProgress(max, progress, false). The first parameter “max” is the complete value of the process and the second parameter “progress” shows how much action is completed. The last parameter “false” shows that it is a determinate progress bar.

  NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
  NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
  builder.setContentTitle("Picture Download")
        .setContentText("Download in progress")
        .setSmallIcon(R.drawable.ic_notification)
        .setPriority(NotificationCompat.PRIORITY_LOW);
  // Issue the initial notification with zero progress
  int PROGRESS_MAX = 100;
  int PROGRESS_CURRENT = 0;
  builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
  notificationManager.notify(notificationId, builder.build());
  // Do the job here that tracks the progress.
  // Usually, this should be in a
  // worker thread
  // To show progress, update PROGRESS_CURRENT and update the notification with:
  // builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
  // notificationManager.notify(notificationId, builder.build());
  // When done, update the notification one more time to remove the progress bar
  builder.setContentText("Download complete").setProgress(0,0,false);
  notificationManager.notify(notificationId, builder.build());

       Remember to update the notification text to show that the operation is complete. If you actually need to
       download a file, you should consider using DownloadManager, which provides its own notification to track your
       download progress.

  • Set a system-wide category
    Android has a special category named system-wide category to determine whether to disturb a user by showing the particular notification if the user has enabled Do Not Disturb mode.
    If the notification comes under the pre-defined categories defined in NotificationCompat the only you should declare it by passing the appropriate category to setCategory() as shown below.

      NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Hello World!")
             .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setCategory(NotificationCompat.CATEGORY_MESSAGE);
    
  • Show an urgent message
    Sometimes the app requires to show an urgent message, such as an upcoming alarm or a phone call, then you can associate full-screen intent with that particularly for the urgent notification.
    If the user’s device is locked, then it will cover the full locked screen to show this message, or if it’s not locked then the notification appears in an expanded form.
    The following code shows how to integrate the notification message with full-screen intent -

      Intent fullScreenIntent = new Intent(this, ImportantActivity.class);
      PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
      NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
             .setSmallIcon(R.drawable.notification_icon)
             .setContentTitle("My notification")
             .setContentText("Hello World!")
             .setPriority(NotificationCompat.PRIORITY_DEFAULT)
             .setFullScreenIntent(fullScreenPendingIntent, true);
    
  • Update a notification
    To update the notification after the user has received it, call the NotificationManagerCompat.notify() again, and pass it a notification with the same ID you used previously. If the previous notification has been dismissed, a new notification is created in its place.

  • Remove a notification
    The notification remains visible until the following action is not performed -

    • Dismiss the notification
    • Click on the notification and you called setAutoCancel() when you created the notification.
    • You call cancel() for a specific notification ID.
    • You call cancelAll(), which removes all of the notifications you previously issued.

About