关于Android O 通知渠道总结

本文是关于针对Android O 通知渠道的总结。

Android O 引入了通知渠道Notification Channels,更好的方便用户管理通知栏消息。

1
2
3
4
5
6
NotificationChannel
public final class NotificationChannel
extends Object implements Parcelable
java.lang.Object
android.app.NotificationChannel

距离上一次总结通知栏相关的东西好像有很久了,可以去这里查看

今天我们从一个基本的通知示例开始,来总结下Android O 通知渠道相关的使用。

基本示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//创建通知栏管理对象
NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
//为了版本兼容 选择V7包下的NotificationCompat进行构造
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
//setTicker 在5.0以上不显示Ticker属性信息
builder.setTicker("状态栏显示的提示");;
//setContentTitle 通知栏通知的标题
builder.setContentTitle("内容标题");
//setContentText 通知栏通知的详细内容
builder.setContentText("内容文本信息");
//setAutoCancel 点击通知的清除按钮是否清除该消息(true/false)
builder.setAutoCancel(true);
//setLargeIcon 通知消息上的大图标
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
//setSmallIcon 通知上面的小图标
builder.setSmallIcon(R.mipmap.ic_launcher);//小图标
//创建一个意图
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.baidu.com"));
PendingIntent pIntent = PendingIntent.getActivity(this, 1, intent, 0);
//setContentIntent 将意图设置到通知上
builder.setContentIntent(pIntent);
//通知默认的声音 震动 呼吸灯
builder.setDefaults(NotificationCompat.DEFAULT_ALL);
//构建通知
Notification notification = builder.build();
//将构建好的通知添加到通知管理器中,执行通知
mNotificationManager.notify(0, notification);

这段代码很简单,已经添加了注释,没有什么可以说的。

差异复现

SDK < 8.0(API 26)

这种情况,上面的示例代码是能无障碍的将通知消息显示出来。

SDK > = 8.0(API 26)

这种情况,上面的示例代码,是死活都不会把通知消息显示出来的。

在Android Oreo上的开发者选项中,新增加了一个show notification channel warnings的选项功能,可以通过Settings > System > Developer options 下找到开启。

再次运行代码后,界面上会弹出类似于下面的这样一个Toast,告知你的通知消息post失败,详细情况查看log

1
2
3
Developer warning for package "com.shoewann.notificationsimple"
Failed to post notification on channel "null"
See log for more details

查看log是这样的:

1
E/NotificationService: No Channel found for pkg=com.shoewann.notificationsimple, channelId=null, id=0, tag=null, opPkg=com.shoewann.notificationsimple, callingUid=10083, userId=0, incomingUserId=0, notificationUid=10083, notification=Notification(channel=null pri=0 contentView=null vibrate=default sound=default tick defaults=0xffffffff flags=0x11 color=0x00000000 vis=PRIVATE)

通过跟踪查看相关源代码,分析到了,在NotificationCompat这个类中的Builder方法。

在版本com.android.support:appcompat-v7:26.1.0的兼容库中,可以看到传一个参数的Builder(Context context)方法已经过期,使用传入两个参数的Builder(@NonNull Context context, @NonNull String channelId)新方法代替。

注意:该新方法需要传入的这两个参数都是标注了@NonNull,也就是不能传入null或者未初始化的变量

兼容代码

通过以上的分析,也就是我们在Android Oreo上面使用Notification,就必须要为你的Notification创建一个Notification Channels(通知渠道)。

创建通知渠道

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
NotificationCompat.Builder builder = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("通知渠道ID",
"通知渠道名称", NotificationManager.IMPORTANCE_DEFAULT);
channel.enableLights(true); //设置开启指示灯,如果设备有的话
channel.setLightColor(Color.RED); //设置指示灯颜色
channel.setShowBadge(true); //设置是否显示角标
channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);//设置是否应在锁定屏幕上显示此频道的通知
channel.setDescription("通知渠道描述");//设置渠道描述
channel.setVibrationPattern(new long[]{100,200,300,400,500,600});//设置震动频率
channel.setBypassDnd(true);//设置是否绕过免打扰模式
mNotificationManager.createNotificationChannel(channel);
createNotificationChannelGroups();
setNotificationChannelGroups(channel);
builder = new NotificationCompat.Builder(this, "通知渠道ID");
builder.setBadgeIconType(BADGE_ICON_SMALL);//设置显示角标的样式
builder.setNumber(3);//设置显示角标的数量
builder.setTimeoutAfter(5000);//设置通知被创建多长时间之后自动取消通知栏的通知。
}else{
builder = new NotificationCompat.Builder(this);
}
//setContentTitle 通知栏通知的标题
builder.setContentTitle("内容标题");
//setContentText 通知栏通知的详细内容
builder.setContentText("内容文本信息");
//setAutoCancel 点击通知的清除按钮是否清除该消息(true/false)
builder.setAutoCancel(true);
//setLargeIcon 通知消息上的大图标
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
//setSmallIcon 通知上面的小图标
builder.setSmallIcon(R.mipmap.ic_launcher);//小图标
//创建一个意图
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.baidu.com"));
PendingIntent pIntent = PendingIntent.getActivity(this, 1, intent, 0);
//setContentIntent 将意图设置到通知上
builder.setContentIntent(pIntent);
//通知默认的声音 震动 呼吸灯
builder.setDefaults(NotificationCompat.DEFAULT_ALL);
//构建通知
Notification notification = builder.build();
//将构建好的通知添加到通知管理器中,执行通知
mNotificationManager.notify(0, notification);

效果图:

android-o-notification-channel-1

向右滑动通知消息,可以显示延迟本条消息显示和设置选项

android-o-notification-channel-2

点击左边的延迟本条消息显示的时间

android-o-notification-channel-3

点击右边的设置选项,可以显示进入操作通知的设置入口

android-o-notification-channel-4

在桌面上的快捷方式上会显示角标

android-o-notification-channel-6

长按快捷方式,会在快捷方式旁边弹出通知栏窗口,显示通知栏消息等信息。

android-o-notification-channel-7

移除通知渠道

1
2
3
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
mNotificationManager.deleteNotificationChannel("通知渠道ID");
}

跳转到通知渠道设置

1
2
3
4
5
6
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_CHANNEL_ID, "通知渠道ID");
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
startActivity(intent);
}

android-o-notification-channel-5

创建通知渠道组

1
2
3
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
mNotificationManager.createNotificationChannelGroup(new NotificationChannelGroup("通知渠道组ID", "通知渠道组名称"));
}

绑定通知渠道组

1
2
3
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
channel.setGroup("通知渠道组ID");
}

本文只是简要的总结了通知渠道的基本用法,还有更多的使用方法,请参考Android官方文档-NotificationChannel。关于本文如有不足之处,欢迎指正,谢谢。

Shoewann wechat
欢迎订阅公众号——“谷愛”
如果觉得本文对您有用,请随意 ¥打赏支持 !