Android Notification 使用详解

721 阅读4分钟

1. Notification 是什么?

Notification 是一种可以在系统的状态栏以及通知面板中显示的消息提示,是 Android系统中一种具有全局效果的通知机制,旨在向用户提供提醒、来自他人的通信或应用中的其他实时信息。

当某个应用程序希望向用户发出一些提示信息,而又不想在前台运行,就可借助 Notification 实现。发出一条通知后,手机上方的状态栏中会显示一个通知图标,下拉状态栏可以看到详细内容。

2. 通知渠道

通知渠道(Notification Channels) ,也被称为通知类别,是Android 8.0(API 级别 26)引入的一个功能,它为开发者提供了更好的管理通知的方式,也使用户能够有更好地控制他们想要接收的通知类型。

在过去,用户没法对不同的信息做区分,要么接受所有信息,要么屏蔽所有信息。

于是,在 Android 8.0 引入通知渠道这个概念。每条通知都要属于一个对应的渠道。每个应用程序可以自由创建当前应用有哪些通知渠道,但这些通知渠道的控制权是掌握在用户手上的,用户可以自由选择这些通知渠道的重要程度,是否响铃、是否振动或者是否要关闭。

使用 NotificationManager 对通知进行管理,使用 NotificationChannel 构建一个通知渠道。创建一个通知渠道至少需要渠道ID渠道名称以及渠道等级这三个参数。

  • 渠道 ID:可以随意定义,只要保持全局唯一性即可。
  • 渠道名称:是给用户看的,需要可以清楚的表达这个渠道的用途。
  • 渠道等级:主要有IMPORTANCE_HIGHIMPORTANCE_DEFAULTIMPORTANCE_LOWIMPORTANCE_MIN。不同重要等级会决定通知的不同行为。用户可以随意手动更改某个渠道的重要等级,开发者无法干预。

NotificationManager 是 Android 系统中用于管理通知的类。它允许应用程序向用户显示各种形式的通知,包括文本、图像、声音、振动等。通过 NotificationManager,开发者可以在应用程序中创建、更新、取消通知,以及与用户进行交互,如点击通知打开特定的活动(Activity)等。在大多数情况下,一个应用程序中只需要一个NotificationManager 实例来管理所有通知。

创建通知渠道:

NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ // Android 8.0 新增 Api。版本判断
    NotificationChannel notificationChannel = new NotificationChannel("normal","Normal", NotificationManager.IMPORTANCE_DEFAULT);
    notificationManager.createNotificationChannel(notificationChannel);
}        

3. 通知的基本用法

通知用法比较灵活,可以在 Activity 里创建,也可以在广播接收器里创建,也可以在服务里创建,在 Activity 里创建的场景比较少。

通过使用 PendingIntent,可以使通知可点击。与 Intent 相似。Intent 倾向于立即执行某个动作,而PendingIntent 倾向于在某个合适的时机执行某个动作,可以理解为延迟执行的 Intent。

public class NotificationActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notification);
        Button sendNotice = findViewById(R.id.send_notice);
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            NotificationChannel notificationChannel = new NotificationChannel("normal","Normal", NotificationManager.IMPORTANCE_DEFAULT);
            notificationManager.createNotificationChannel(notificationChannel);
        }
        sendNotice.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(NotificationActivity.this, OpenNotificationActivity.class);
                PendingIntent pi = PendingIntent.getActivity(NotificationActivity.this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
                //Builder接收两个参数,context和渠道ID
                Notification notification =  new NotificationCompat.Builder(NotificationActivity.this,"normal")
                        .setContentTitle("This is content title")
                        .setContentText("真正的平静,不是避开车马喧嚣,而是在心中修篱种菊。尽管如流往事,每一天都涛声依旧,只要我们消除执念,便可寂静安然。愿每个人,在纷呈世相中不会迷失荒径,可以端坐磐石上,醉倒落花前。")
                        .setWhen(System.currentTimeMillis())
                        .setSmallIcon(R.drawable.a)//只能使用纯alpha图层的图片进行设置,小图标会显示在系统状态栏上。
                        .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.a))//当下拉系统状态栏时显示。
                        .setContentIntent(pi)
                        .setAutoCancel(true)
                        .setStyle(new NotificationCompat.BigTextStyle().bigText("真正的平静,不是避开车马喧嚣,而是在心中修篱种菊。尽管如流往事,每一天都涛声依旧,只要我们消除执念,便可寂静安然。愿每个人,在纷呈世相中不会迷失荒径,可以端坐磐石上,醉倒落花前。"))
                        .setStyle(new NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(getResources(),R.drawable.a)))
                        .build();
                notificationManager.notify(1,notification);//第一个参数id,要保证每个通知指定的id都不同
            }
        });
    }
}

通知图标消失两种方法:setAutoCancel(true)cancel()

//点击通知打开的Activity
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.cancel(1);//1为通知id