目录
9.2 使用通知
通知(notification )是 Android 系统中比较有特色的一个功能,当某个应用程序希望向用户发 出一些提示信息,而该应用程序又不在前台运行时,就可以借助通知来实现。发出一条通知 后,手机最上方的状态栏中会显示一个通知的图标,下拉状态栏后可以看到通知的详细内容。 Android 的通知功能自推出以来就大获成功,连 iOS 系统也在5.0 版本之后加入了类似的功能。
9.2.1 创建通知渠道
然而,通知这个功能的设计初衷是好的,后来却被开发者给玩坏了。
每发出一条通知,都可能意味着自己的应用程序会拥有更高的打开率,因此有太多太多的应用会想尽办法地给用户发送通知,以博取更多的展示机会。站在应用自身的角度来看,这么做或 许并没有什么错;但是站在用户的角度来看,如果每一个应用程序都这么做的话,那么用户手 机的状态栏就会被各式各样的通知信息堆满,不胜其烦。
虽然 Android 系统允许我们将某个应用程序的通知完全屏蔽,以防止它一直给我们发送垃圾信 息,但是在这些信息中,也可能会有我们所关心的内容。比如说我希望收到某个我所关注的人 的微博更新通知,但是却不想让微博一天到晚给我推送一些明星的花边新闻。在过去,用户是 没有办法对这些信息做区分的,要么同意接受所有信息,要么屏蔽所有信息,这也是 Android 通 知功能的痛点。
于是,Android 8.0 系统引入了通知渠道这个概念。
什么是通知渠道呢?顾名思义,就是每条通知都要属于一个对应的渠道。每个应用程序都可以 自由地创建当前应用拥有哪些通知渠道,但是这些通知渠道的控制权是掌握在用户手上的。用 户可以自由地选择这些通知渠道的重要程度,是否响铃、是否振动或者是否要关闭这个渠道的 通知。
拥有了这些控制权之后,用户就再也不用害怕那些垃圾通知的打扰了,因为用户可以自主地选 择关心哪些通知、不关心哪些通知。以刚才的场景举例,微博就可以创建两种通知渠道,一个 关注,一个推荐。而我作为用户,如果对推荐类的通知不感兴趣,那么我就可以直接将推荐通 知渠道关闭,这样既不影响我接收关心的通知,又不会让那些我不关心的通知来打扰我了。
对于每个应用来说,通知渠道的划分是非常考究的,因为通知渠道一旦创建之后就不能再修改 了,因此开发者需要仔细分析自己的应用程序一共有哪些类型的通知,然后再去创建相应的通 知渠道。这里我们参考一下 Twitter 的通知渠道划分,如 图9.5 所示。
![](https://img-blog.csdnimg.cn/direct/d7c91c1a347149fe88fcd39aa2846e1b.png)
可以看到,Twitter 根据自己的通知类型,对通知渠道进行了非常详细的划分。这样用户的自主 选择性就比较高了,也就大大降低了用户因不堪其垃圾通知的骚扰而将应用程序卸载的概率。
而我们的应用程序如果想要发出通知,也必须创建自己的通知渠道才行,下面我们就来学习一 下创建通知渠道的详细步骤。
首先需要一个 NotificationManager 对通知进行管理,可以通过调用 Context 的 getSystemService() 方法获取。getSystemService() 方法接收一个字符串参数用于确定 获取系统的哪个服务,这里我们传入Context.NOTIFICATION_SERVICE 即可。因此,获取 NotificationManager 的实例就可以写成:
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
接下来要使用 NotificationChannel 类构建一个通知渠道,并调用 NotificationManager 的 createNotificationChannel() 方法完成创建。由于 NotificationChannel 类和 createNotificationChannel() 方法都是Android 8.0 系统中新增的API,因此我们在使用 的时候还需要进行版本判断才可以,写法如下:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(channelId, channelName, importance)
manager.createNotificationChannel(channel)
}
创建一个通知渠道至少需要渠道ID、渠道名称以及重要等级这3个参数,其中渠道ID可以随便定义,只要保证全局唯一性就可以。渠道名称是给用户看的,需要可以清楚地表达这个渠道的用 途。通知的重要等级主要有IMPORTANCE_HIGH、IMPORTANCE_DEFAULT、 IMPORTANCE_LOW、IMPORTANCE_MIN这几种,对应的重要程度依次从高到低。不同的重要等级会决定通知的不同行为,后面我们会通过具体的例子进行演示。当然这里只是初始状态下的 重要等级,用户可以随时手动更改某个通知渠道的重要等级,开发者是无法干预的。
9.2.2 通知的基本用法
了解了如何创建通知渠道之后,下面我们就来看一下通知的使用方法吧。通知的用法还是比较灵活的,既可以在 Activity 里创建,也可以在 BroadcastReceiver 里创建,当然还可以在后面 我们即将学习的 Service 里创建。相比于BroadcastReceiver 和 Service ,在 Activity 里创建通知的场景还是比较少的,因为一般只有当程序进入后台的时候才需要使用通知。
不过,无论是在哪里创建通知,整体的步骤都是相同的,下面我们就来学习一下创建通知的详细步骤。
首先需要使用一个 Builder 构造器来创建 Notification 对象,但问题在于,Android 系统的每 一个版本都会对通知功能进行或多或少的修改,API不稳定的问题在通知上凸显得尤其严重,比 方说刚刚介绍的通知渠道功能在 Android 8.0 系统之前就是没有的。那么该如何解决这个问题呢?其实解决方案我们之前已经见过好几回了,就是使用 AndroidX库中提供的兼容API。 AndroidX库中提供了一个 NotificationCompat 类,使用这个类的构造器创建 Notification 对象,就可以保证我们的程序在所有 Android 系统版本上都能正常工作了,代 码如下所示:
val notification = NotificationCompat.Builder(context, channelId).build()
NotificationCompat.Builder 的构造函数中接收两个参数:第一个参数是context,这个 没什么好说的;第二个参数是渠道ID,需要和我们在创建通知渠道时指定的渠道ID相匹配才 行。
当然,上述代码只是创建了一个空的 Notification 对象,并没有什么实际作用,我们可以在 最终的 build() 方法之前连缀任意多的设置方法来创建一个丰富的 Notification