Android 8.0 + notification bar adaptation

Posted by matafy on Fri, 11 Feb 2022 06:30:25 +0100

Everyone is familiar with the notification bar. It should be regarded as the basic functional component of the device. Push messages, task reminders, alarm clock reminders, etc. need to be displayed to users through the notification bar of the device. Therefore, an eye-catching and friendly notification is very important, but in this chaotic environment of android ecology, there are many messy notifications, I didn't want to receive it, but I saw the sky being pushed and bombed by various app s.

Before Android 8.0, some well-done manufacturers will provide a notification switch for each app, but after this permission is turned off, they can no longer receive notifications, so that any notifications of subsequent apps can not be displayed to users unless users turn on the notification switch of APP again.

Maybe Google is aware of this problem, so on Android 8.0, notification channel came into being. For devices with targetSdkVersion on 26 and, if you want to display app notifications, you must register the corresponding notification channels. An app can register multiple channels, and the user can set the switching state of a channel by himself. If the notification of a channel is turned off, any notification of the channel will not be displayed to the user, The notifications of other channels are not affected

Figure 1 understand the basic composition of the notice

Before Android 8.0, if you want to display a message on the Notification bar, you basically create a Notification first, and then directly show() by the NotificationManager. There is no problem

public void notify(int id) {
    Notification notification = new NotificationCompat.Builder(this)
                .setAutoCancel(true)
                .setSmallIcon(getSmallIcon())
                .setLargeIcon(getLargeIcon())
                .setContentTitle(title)
                .setContentText(body)
                .setContentIntent(pendingIntent)
                .build();

    getManager().notify(id, notification);
 }

However, if you execute this code on Android 8.0, the notification will not be displayed. You need to set the NotificationChannel, and you must register the channel before setting the channel

NotificationChannel channel = new NotificationChannel(
                "DEFAULT_CHANNEL_ID",
                "Push notification", 
                NotificationManager.IMPORTANCE_HIGH
);
 getManager().createNotificationChannel(channel);

As you can see, the NotificationChannel construction method has three parameters: NotificationChannel(String id, CharSequence name, int , importance)

id: the unique identifier of the channel. Different channel IDs of the same app cannot be repeated

name: channel description

Importance: the importance of the channel notification

Finally, register the channel through NotificationManager. Note: the channel must be created before notify(). Repeated creation of existing channels will not have any impact

Now, we have created a channel. Similarly, there are differences in the way android 8.0 and above and 7.0 and below create notifications

 private NotificationCompat.Builder getNotificationBuilderByChannel(String channelId) {
        NotificationCompat.Builder builder;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder = new NotificationCompat.Builder(getApplicationContext(), channelId);
        } else {
            builder = new NotificationCompat.Builder(this).setSound(soundUri);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//Priority setting & & above 7.0
                builder.setPriority(NotificationManager.IMPORTANCE_HIGH);
            } else {
                builder.setPriority(NotificationCompat.PRIORITY_HIGH);
            }
        }
        return builder;
    }

After 8.0, notificationcompat Builder (context) has been abandoned, so it's better to use the latest API to create it. Although there is no channel under 8.0, if you look at the source code, you will find that notificationcompat Notificationcompat is called internally by Builder (context) Builder (context, context, String channelId), but the channelId is null. So now let's look at notificationcompat The builder is created in the same way.

   /** @deprecated */
        @Deprecated
        public Builder(Context context) {
            this(context, (String)null);
        }

In addition, it should be noted that different versions set the priority of notifications in different ways. The priority of notifications 8.0 and above is set in channel, and the priority below 8.0 is set in notificationcompat Set in Builder

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(DEFAULT_CHANNEL,
                    "My notice Channel", NotificationManager.IMPORTANCE_HIGH);         
    }


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//Priority setting below 8.0 & & 7.0 and above
             builder.setPriority(NotificationManager.IMPORTANCE_HIGH);
        } else {
             builder.setPriority(NotificationCompat.PRIORITY_HIGH);
    }

For the specific introduction of each attribute in the priority, please refer to the official Android documentation android developers (no need to climb over the wall)

You may have noticed why I only set it below 8.0 setSound(soundUri); So how do 8.0 + set the sound of notification?

This is because 8.0 + sets the notification sound effect when creating the channel

AudioAttributes att = new AudioAttributes.Builder()
                    .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                    .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
                    .build();
NotificationChannel channel = new NotificationChannel(DEFAULT_CHANNEL,"My notice 
                    Channel", NotificationManager.IMPORTANCE_HIGH);

channel.setSound(soundUri, att); 
getManager().createNotificationChannel(channel);

channel.setSound(soundUri, att); In addition to setting the uri of the sound effect, you also need to set the audio properties. One advantage of this method is that you can set different notification sound effects for different channels. If you do not set a custom uri, the default notification ringtone of the mobile phone will be used

Now, our notification bar has been adapted to various versions of api, but on some mobile phones (oppo...), After the application installation is completed, the notification is closed by default. At this time, we can judge whether the notification switch is on through the api, so as to guide the user to manually turn on the notification in the setting

NotificationManagerCompat.from(context).areNotificationsEnabled();

You should also notice that I create a Notification here using NotificationCompat Builder, in fact, can notify in another way Note that the reason for choosing the former here is that NotificationCompat is compatible with lower versions, and some api version related packages have been made internally for us. Here, we refer to a document on the official website for explanation

The creation method of notice bar of each version has been introduced. In addition, it is from Android 8 Starting from 0, it supports the display of notification red dots on the app startup icon. Users can long press the application icon to view the notification of the application. The user can then turn off or process notifications from the menu by sliding left and right. The following is a brief introduction to how to display large text and large picture in the notice bar

By default, only one line of text can be displayed in the Notification bar. If our text is too long, it will lead to incomplete text display (ending with...). At this time, we can set the style of Notification display when creating Notification to realize the display of large text

builder.setStyle(new NotificationCompat
                       .BigTextStyle()//Large text style
                       .setBigContentTitle(title)//title displayed when the notification is expanded
                       .bigText(body)//All text displayed when the notification is expanded
);

The Android notification bar supports displaying large pictures, but can only receive parameters of Bitmap type. Therefore, if you want to display network pictures, you need to convert the pictures to Bitmap by yourself

builder.setStyle(new NotificationCompat
                       .BigPictureStyle()//Large picture mode
                       .setBigContentTitle(title)
                       .bigLargeIcon(imgBitmap)Thumbnail displayed when notification is expanded
                       .bigPicture(imgBitmap)//Large image displayed when the notification is expanded
);

Finally, let's take a look at the effect

 

Topics: Android