在这之前就知道Oreo系统对于通知做了一个渠道的划分,之前有一次做东西还碰到了这个问题,但是一直没有正儿八经的总结一下,这里来做下总结。
背景
首先为什么要有这个东西?
Google在通知栏上做了很多优化,具体可以参考
https://developer.android.com/guide/topics/ui/notifiers/notifications
官网所给粗来的通知更新日志。其中Android5.0 和 Android 8.0 的更新也是比较大的。
Android8.0 所解决的痛点是 对于一个app的通知,如何接收到有用的,过滤掉没用的。比如说我想收到QQ消息,而不想收到QQ推送的广告(好像没见QQ推送过,随意举个例子),我希望能自己设置接受哪些通知。
于是对于这个问题,Google给出的解决方法是通知渠道。
对于通知渠道,就是把各类通知信息投放到不同的渠道中,用户可以对每个渠道进行操作来限制此类通知的发出规则。(表示不太用这个功能。)
看下微信,虽然是MIUI定制的,但是也能看出最下面通知的类型,其中第一种就是微信消息的通知,另一种就是下载时候用的通知。

点击消息的通知,看到的界面如下。

对于每个通知渠道,我们可以配置是否允许通知,重要程度,提示方式等等一下属性,而这些属性,需要在程序里初始化,并且初始化之后程序再无法修改。
创建一个渠道
public void createNotificationChannel(){
if (SDK_INT >= VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("_message","消息通知",NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("这是用于接受消息的通知渠道");
notificationManager.createNotificationChannel(channel);
}
}
其中,创建一个通知渠道需要在8.0以上。
而创建通知渠道需要三个参数,一是id,二是介绍,三是通知重要程度。
其中id是唯一标识,在同一App中不能重复,介绍给用户看的,方便用户对渠道作区分,他们的长度不能太长,否则会被系统做截断;重要程度有几个等级,每个等级的配置不一样,比如说是否开启闪光灯,是否震动等等。
那么配置之后的效果图如下。

这里需要注意一个地方,通知渠道刚安装App是不显示的,只有发出通知的时候才会显示。
同时要注意,如果在代码中修改了渠道信息,也是要发出通知才能看到设置界面的更新的。(目前在MIUI是这样,不确定其他系统是不是。)
对于渠道,我们可以设置很多属性。

渠道需要在使用前创建,并且重复创建也没事,因为系统会帮你判断是否已经创建,所以不会浪费很多资源。
发送一个通知
if(SDK_INT >= 26){
NotificationCompat.Builder builder = new NotificationCompat.Builder(context,channelId)
.setContentTitle(title)
.setContentText(content)
.setAutoCancel(true) .setLargeIcon(BitmapFactory.decodeResource(context.getApplicationContext().getResources(), R.mipmap.ic_launcher_round))
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(intent);
NotificationManager notificationManager = (NotificationManager) context.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(id,notification);
}
上述代码说的是在android26上面的创建一个通知,其中所使用的Builder就是新的API所定义的方法,需要传入一个channelId,传入的channelId必须是属于已经创建的channel的,否则会报错。
通知的重要程度
通知的重要程度分为几个等级,其中IMPORTANCE_NONE说明通知已被关闭,其余几个等级权限逐渐放高。


当然如果消息很重要,通知还被用户关掉了,那需要引导用户把通知开关打开。
public void openSetting(){
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = notificationManager.getNotificationChannel("渠道id");
if(channel.getImportance() == NotificationManager.IMPORTANCE_NONE){
Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE,"你的应用包名");
intent.putExtra(Settings.EXTRA_CHANNEL_ID,"渠道id");
context.startActivity(intent);
}
}
}
网友评论