Detailed Android Notification

Catalog introduction

  • 1.Notification brief overview
  • 1.1 Overview of basic use
  • 1.2 Notification bar mind map structure
  • 2. Notification related analysis
  • 2.1 Common uses
  • 2.2 Corresponding official documents
  • 2.3 The main classes of the notification bar: Notification and NotificationManager
  • 2.4 Process Module
  • 3.Basic operation of Notification
  • 3.1 Notification creates the necessary properties
  • 3.2 Simple creation steps of Notification
  • 3.3 About the difference between setSmallIcon() and setLargeIcon()
  • 3.4 Action property of Notification [Interaction]
  • 3.5 Update Notification
  • 3.6 Cancel Notification
  • 3.7 Setting the flag attribute
  • 3.8 Setting the notification effect of Notification
  • 3.9 Set custom Notification notification bar layout
  • 4.Notification related attribute description
  • 4.1 Description of PendingIntent
  • 4.2 Create the return stack PendingIntent
  • 4.3 Points to note
  • 5. Some source code analysis thinking
  • 5.1 What is RemoteView?
  • 5.2 View the source code to understand how Notification creates the layout
  • 6. About others
  • 6.1 Reference case
  • 6.2 Changelog
  • v1.0 written on June 18, 2016
  • v1.1 updated on 12/6/17, reorganized notes
  • 6.3 About my blog

0. Remarks

1.Notification brief overview

  • 1.1 Overview of basic use
  • Notification is a notification with global effect that can be displayed in the notification bar of the system. When the APP sends a notification to the system, it will first be displayed in the notification bar in the form of an icon. Users can pull down the notification bar to view the details of the notification. Both the notification bar and the drawer notification bar are controlled by the system and can be viewed by the user at any time.
  • 1.2 Notification bar mind map structure
  • The general structure of the mind map, several key points
  • Notificaiton -- service -- BroadcastReceiver -- Intent (application of attributes such as flag and Action) -- PendingIntent
    sighed:
  • The expansion and use of a Notificaiton notification will involve the cooperation with the four major components, so learn the overall knowledge system.
  • Then you will want to notify what is the connection with the four major components?
  • 1. For example, in a music player, music is played in the background. Since the service is running in the background, we cannot see what it intends to do. At this time, a reminder can be displayed through Notificaiton. For specific cases, please refer to my music player: https://github.com/yangchong211/YCVideoPlayer
  • 2. For example, in the music player, the program runs in the background, click the previous song, the next song, etc. on the notification bar of the music player, then the service service can be combined with the BroadcastReceiver broadcast.
  • 3. Intent is handled as an intent, which is closely integrated with the click time of Notificaiton, and is closely and inseparably linked with BroadcastReceiver and service.
    (The service notifies Notificaiton through BroadcastReceiver in the background to display relevant things, and completes the user's intent operation through Intent)

2. Notification related analysis

  • 2.1 Common uses

  • Display received short messages, instant messages and other information (such as QQ, WeChat, Sina, SMS)

  • Display client push messages, such as advertisements, discounts, version updates, recommended news, etc. Commonly used third-party SDKs are: JPush, Getui, Carrier Pigeon, NetEase Yunxin (emphasis on IM), Alibaba Cloud Push

  • Shows what is going on, for example: programs running in the background, such as music playback progress, download progress, etc.

  • The first two points can be boiled down to interacting with users, and the third point is real-time task reminders, but it is undeniable that the third point will also interact with users.

  • 2.2 Corresponding official documents

官方:http://developer.android.com/design/patterns/notifications.html
使用教程 :http://developer.android.com/training/notify-user/index.html 
开发文档 :http://developer.android.com/reference/android/app/Notification.html
  • 2.3 The main classes of the notification bar: Notification and NotificationManager

  • NotificationManager: It is the management class for status bar notifications, responsible for sending notifications, clearing notifications and other operations.

  • Notification is a notification information class, which corresponds to the various properties of the notification bar [ Note : Use the builder mode to build a Notification object. Since Notification.Builder only supports Android 4.1 and later versions, in order to solve the compatibility problem, Google added the NotificationCompat.Builder class to Android Support v4.

  • 2.4 Process Module

  • The first step: Create a notification bar Builder construction class (Create a Notification Builder)

  • Step 2: Define the Notification's Action (Define the Notification's Action)

  • Step 3: Set the Notification's Click Behavior

  • Step 4: Issue the Notification

3.Basic operation of Notification

  • 3.1 Notification creates the necessary properties, which must be set
  • 3.1.1 Properties that must be added
  • Small icon, set by the setSmallIcon() method
  • Title, set by the setContentTitle() method
  • Content, set by the setContentText() method
  • 3.2 Notification creation steps
  • 3.2.1 The creation of Notification mainly involves Notification.Builder, Notification, NotificationManager
    Notification.Builer: Use the builder pattern to build the Notification object. Since Notification.Builder only supports Android 4.1 and later versions, in order to solve compatibility issues, Google added the NotificationCompat.Builder class to Android Support v4. For some features after Android 4.1, even if NotificationCompat.Builder supports this method, it will not work in previous versions.
  • Notification : Notification corresponding class, save notification-related data.
  • The NotificationManager is used when sending notifications to the system.
  • NotificationManager : NotificationManager is the notification management class, which is a system service. Call the notify() method of NotificationManager to send a notification to the system.
  • 3.2.2 Notification creation steps and code
// 创建一个NotificationManager的引用
NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
// 定义Notification的各种属性
Notification.Builder mBuilder = new Notification.Builder(this.getApplicationContext())
        .setSound(android.provider.Settings.System.DEFAULT_NOTIFICATION_URI)        //
        .setSmallIcon(R.mipmap.ic_launcher)                                         //设置通知的图标
        .setTicker("有新消息呢")                                                     //设置状态栏的标题
        .setContentTitle("这个是标题")                                               //设置标题
        .setContentText("这个是内容")                                                //消息内容
        .setDefaults(Notification.DEFAULT_ALL)                                      //设置默认的提示音
        .setPriority(Notification.PRIORITY_DEFAULT)                                 //设置该通知的优先级
        .setOngoing(false)                                                          //让通知左右滑的时候不能取消通知
        .setPriority(Notification.PRIORITY_DEFAULT)                                 //设置该通知的优先级
        .setWhen(System.currentTimeMillis())                                        //设置通知时间,默认为系统发出通知的时间,通常不用设置
        .setAutoCancel(true);                                                       //打开程序后图标消失
//处理点击Notification的逻辑
Intent resultIntent = new Intent(this, TestActivity.class);
resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);           //添加为栈顶Activity
resultIntent.putExtra("what",5);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this,5,resultIntent,PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
//发送
mNotificationManager.notify(1, mBuilder.build());
//结束广播
//mNotificationManager.cancel(1);
  • 3.3 About the difference between setSmallIcon() and setLargeIcon()
  • There are two methods in NotificationCompat.Builder to set the size of the notification icon. What is the difference between these two methods?
  • When setSmallIcon() and setLargeIcon() exist at the same time, smallIcon is displayed on the lower right corner of the notification, and largeIcon is displayed on the left
  • When only setSmallIcon() is set, smallIcon is displayed on the left. Look at the picture below and you will understand.
  • For some ROMs, the source code may have been modified. For example, there is no difference between the large icon and the small icon notified on MIUI.
  • The effect is shown in the figure:
    [Image upload failed...(image-71383e-1516955811548)]
  • 3.4 Action property of Notification
  • Set an Action, so that you can directly jump to an Activity of the App, start a Service or send a Broadcast. Otherwise, Notification can only have the effect of notification, but not interact with the user.
  • The specific code is as follows:
//创建intent
Intent resultIntent = new Intent(this, TestActivity.class);
resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);           //添加为栈顶Activity
resultIntent.putExtra("what",5);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this,5,resultIntent,PendingIntent.FLAG_UPDATE_CURRENT);
//发送pendingIntent
mBuilder.setContentIntent(resultPendingIntent);
  • 3.5 Update Notification
  • Updating a notification is very simple, you only need to send a notification with the same ID again. If the previous notification has not been canceled, the related properties of the notification will be updated directly; if the previous notification has been canceled, a new notification will be created. .
    Update notifications work in the same way as sending notifications.
  • 3.6 Cancel Notification
  • There are 5 ways to cancel the notification:
  • Clicking the clear button in the notification bar will clear all clearable notifications
  • Notifications with setAutoCancel() or FLAG_AUTO_CANCEL set, which clears when clicked
  • Call the cancel(int id) method through NotificationManager to clear the notification with the specified ID
  • Call the cancel(String tag, int id) method through NotificationManager to clear the notification of the specified TAG and ID
  • Call the cancelAll() method through NotificationManager to clear all notifications sent by the app before
  • Precautions
  • If you create a notification through the NotificationManager.notify(String tag, int id, Notification notify) method, you can only clear the corresponding notification through the NotificationManager.cancel(String tag, int id) method, call NotificationManager.cancel(int id) ) is invalid.
  • 3.7 Setting the flag attribute
  • Setting FLAG_NO_CLEAR means
  • The setting notification cannot be cleared by the clear button in the status bar, nor can it be cleared manually, but it can be cleared by the cancel() method.
  • Code:
private void sendNotification9() {
    Notification.Builder mBuilder = new Notification.Builder(this.getApplicationContext())
            .setSound(android.provider.Settings.System.DEFAULT_NOTIFICATION_URI)
            .setSmallIcon(R.mipmap.ic_launcher)                                        //设置通知的图标
            .setTicker("有新消息呢9")                                                    //设置状态栏的标题
            .setContentTitle("这个是标题9")                                              //设置标题
            .setContentText("这个是内容9")                                                //消息内容
            .setDefaults(Notification.DEFAULT_ALL)                                      //设置默认的提示音
            .setOngoing(false)                                                          //让通知左右滑的时候不能取消通知
            .setAutoCancel(true);                                                        //打开程序后图标消失
    Notification notification = mBuilder.build();
    //设置 Notification 的 flags = FLAG_NO_CLEAR
    //FLAG_NO_CLEAR 表示该通知不能被状态栏的清除按钮给清除掉,也不能被手动清除,但能通过 cancel() 方法清除
    //flags 可以通过 |= 运算叠加效果
    notification.flags |= Notification.FLAG_NO_CLEAR;

    //获取NotificationManager 对象
    mNotificationManager.notify(9, notification);
}
//取消通知:
if(mNotificationManager!=null){
    mNotificationManager.cancelAll();
}
  • 3.8 Setting the notification effect of Notification
  • Notification has three kinds of bell effects: vibration, bell, and breathing light, which can be set by the setDefaults(int defualts) method. The Default property has the following four types. Once the Default effect is set, the custom effect will be invalid. The landlord stepped on the pit here, but after adjusting it for a long time, I couldn't find why the custom effect disappeared. Forget everyone to be careful.
//设置系统默认提醒效果,一旦设置默认提醒效果,则自定义的提醒效果会全部失效。具体可看源码//添加默认震动效果,需要申请震动权限//<uses-permission android:name="android.permission.VIBRATE" />
Notification.DEFAULT_VIBRATE
//添加系统默认声音效果,设置此值后,调用setSound()设置自定义声音无效
Notification.DEFAULT_SOUND
//添加默认呼吸灯效果,使用时须与 Notification.FLAG_SHOW_LIGHTS 结合使用,否则无效
Notification.DEFAULT_LIGHTS
//添加上述三种默认提醒效果
Notification.DEFAULT_ALL
  • In addition to the above settings for the default notification effect of Notification, you can also set the notification effect through the following FLAGs.
//提醒效果常用 Flag//三色灯提醒,在使用三色灯提醒时候必须加该标志符
Notification.FLAG_SHOW_LIGHTS
//发起正在运行事件(活动中)
Notification.FLAG_ONGOING_EVENT
//让声音、振动无限循环,直到用户响应 (取消或者打开)
Notification.FLAG_INSISTENT
//发起Notification后,铃声和震动均只执行一次
Notification.FLAG_ONLY_ALERT_ONCE
//用户单击通知后自动消失
Notification.FLAG_AUTO_CANCEL
//只有调用NotificationManager.cancel()时才会清除
Notification.FLAG_NO_CLEAR
//表示正在运行的服务
Notification.FLAG_FOREGROUND_SERVICE
  • Set default reminders
// 添加默认声音提醒
builder.setDefaults(Notification.DEFAULT_SOUND);
// 添加默认呼吸灯提醒,自动添加FLAG_SHOW_LIGHTS
builder.setDefaults(Notification.DEFAULT_LIGHTS);
  • Set ringtone properties, rarely used
private void sendNotification11() {
    Notification.Builder builder = new Notification.Builder(this)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle("我是伴有铃声效果的通知11")
            .setContentText("美妙么?安静听~11")
            //调用系统默认响铃,设置此属性后setSound()会无效
            //.setDefaults(Notification.DEFAULT_SOUND)
            //调用系统多媒体裤内的铃声
            //.setSound(Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"2"));
            //调用自己提供的铃声,位于 /res/values/raw 目录下
            .setSound(Uri.parse("android.resource://com.yc.cn.ycnotification/" + R.raw.hah));
    //另一种设置铃声的方法
    //Notification notify = builder.build();
    //调用系统默认铃声
    //notify.defaults = Notification.DEFAULT_SOUND;
    //调用自己提供的铃声
    //notify.sound = Uri.parse("android.resource://com.yc.cn.ycnotification/"+R.raw.sound);
    //调用系统自带的铃声
    //notify.sound = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"2");
    //mManager.notify(11,notify);
    mNotificationManager.notify(11, builder.build());
}
  • Set vibration properties
private void sendNotification12() {
    //震动也有两种设置方法,与设置铃声一样,在此不再赘述
    long[] vibrate = new long[]{0, 500, 1000, 1500};
    Notification.Builder builder = new Notification.Builder(this)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle("我是伴有震动效果的通知")
            .setContentText("颤抖吧,逗比哈哈哈哈哈~")
            //使用系统默认的震动参数,会与自定义的冲突
            //.setDefaults(Notification.DEFAULT_VIBRATE)
            //自定义震动效果
            .setVibrate(vibrate);
    //另一种设置震动的方法
    //Notification notify = builder.build();
    //调用系统默认震动
    //notify.defaults = Notification.DEFAULT_VIBRATE;
    //调用自己设置的震动
    //notify.vibrate = vibrate;
    //mManager.notify(3,notify);
    mNotificationManager.notify(12, builder.build());
}
  • 3.9 Set custom Notification notification bar layout
  • The code is as follows. Note that only part of the code is taken here. The complete code can be downloaded from github's complete project: https://github.com/yangchong211/YCNotification
.setContent(getRemoteViews())                                              // 设置通知栏的布局
//创建自定义布局
private RemoteViews getRemoteViews() {
    RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notification_mobile_play);
    // 设置 点击通知栏的上一首按钮时要执行的意图
    remoteViews.setOnClickPendingIntent(R.id.btn_pre, getActivityPendingIntent(11));
    // 设置 点击通知栏的下一首按钮时要执行的意图
    remoteViews.setOnClickPendingIntent(R.id.btn_next, getActivityPendingIntent(12));
    // 设置 点击通知栏的播放暂停按钮时要执行的意图
    remoteViews.setOnClickPendingIntent(R.id.btn_start, getActivityPendingIntent(13));
    // 设置 点击通知栏的根容器时要执行的意图
    remoteViews.setOnClickPendingIntent(R.id.ll_root, getActivityPendingIntent(14));
    remoteViews.setTextViewText(R.id.tv_title, "标题");    // 设置通知栏上标题
    remoteViews.setTextViewText(R.id.tv_artist, "艺术家");  // 设置通知栏上艺术家
    return remoteViews;
}

4.Notification related attribute description

  • 4.1 Description of PendingIntent
  • 4.1.1 What is PendingIntent
  • PendingIntent is slightly different from Intent. It can set the number of executions. It is mainly used in remote service communication, alarm, notification, launcher, and short message. It is used less in general.
  • 4.1.2 Basic description of PendingIntent
  • PendingIntent is a special Intent, which literally can be interpreted as a delayed Intent, used to execute a specific Action after an event ends. This can also be verified from the notification with Action above, which will only be executed when the user clicks on the notification.
  • PendingIntent is a flag (reference) of an object managed and held by the Android system to describe and obtain raw data. That is, even if the process that created the PendingIntent object is killed, the PendingItent object is still available in other processes.
    PendingIntent is used in daily text messages, alarm clocks, etc.
  • 4.1.3 PendingIntent related attribute flag
PendingIntent的位标识符:
FLAG_CANCEL_CURRENT:如果当前系统中已经存在一个相同的 PendingIntent 对象,那么就将先将已有的 PendingIntent 取消,然后重新生成一个 PendingIntent 对象。
FLAG_NO_CREATE:如果当前系统中不存在相同的 PendingIntent 对象,系统将不会创建该 PendingIntent 对象而是直接返回 null 。
FLAG_ONE_SHOT:该 PendingIntent 只作用一次。
FLAG_UPDATE_CURRENT:如果系统中已存在该 PendingIntent 对象,那么系统将保留该 PendingIntent 对象,但是会使用新的 Intent 来更新之前 PendingIntent 中的 Intent 对象数据,例如更新 Intent 中的 Extras 。
  • 4.1.4 Three ways to obtain PendingIntent
  • It can be seen that it supports a variety of corresponding methods, including Activity, Broadcast, Service, and you can choose according to your own needs.
//获取一个用于启动 Activity 的 PendingIntent 对象public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags);
//获取一个用于启动 Service 的 PendingIntent 对象public static PendingIntent getService(Context context, int requestCode, Intent intent, int flags);
//获取一个用于向 BroadcastReceiver 广播的 PendingIntent 对象public static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)
  • 4.2 Create the return stack PendingIntent
  • 4.2.1 Adding back stack code
    By default, an Activity is launched from a notification, and pressing the back key will return to the home screen.
    But sometimes there is a need to press the return key to remain in the current application, which requires the use of TaskStackBuilder.
Notification.Builder mBuilder = new Notification.Builder(context)
                .setSound(android.provider.Settings.System.DEFAULT_NOTIFICATION_URI)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("广播接受者标题,小杨")
                .setContentText("广播接受者内容,扯犊子")
                .setAutoCancel(true);
Log.i(TAG, "onReceive: intent" + intent.getClass().getName());
Intent resultIntent = new Intent(context, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
//将该Activity添加为栈顶
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager = (NotificationManager)
        context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
  • 4.3 Points to note
  • If the user's phone is in silent mode, then setting the ringtone or vibration effect will not work

5. Some source code analysis thinking

  • 5.1 What is RemoteView?
  • 5.1.1 What is RemoteView?
  • Why is Notification not designed to be used in the same way as a normal View? The reason is very simple! The status bar is not managed by your application alone. The status bar is managed by the Android system. Your Notification can only be displayed through the Notification service. So it is designed to represent a Notification with a Notification instance, and then submit it to the Notification service through the notificationManager.notify function.
  • 5.1.2 What is Notification service? It is an independent thread!
  • Another question arises. Displaying View across threads. How to display it? It is not to display View in this application. Here we have to borrow RemoteView.
  • RemoteView is understood as the encapsulation of a View, and then submits the RemoteView to other threads. Other threads receive the RemoteView and parse the information in the View to display it.
  • 5.1.3 When using the notification system that comes with the system, a default RemoteView will be created!
  • The system uses R.layout.notification_template_material_base by default to produce a RemoteView.
    As for how to find the layout here, please see the source code analysis below
  • 5.2 View the source code to understand how Notification creates the layout
  • 5.2.1 First look at the build code in Notification

     

    image

  • 5.2.2 Then look at the createContentView() method in the figure above

     

    image

  • 5.2.3 Then look at the createContentView() method in the figure above

     

    image

6. About others



Author: Xiaoxiang Jianyu_Link
: https://www.jianshu.com/p/514eb6193a06
Source: Jianshu
The copyright belongs to the author. For commercial reprints, please contact the author for authorization, and for non-commercial reprints, please indicate the source.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325296218&siteId=291194637