当我们的应用想在Android 8.0, API level 26上面发送一个通知的时候,我们必须要给通知设置一个Channel,比如如果我们做一个IM,我们可以将用户的消息通知设置为一个Channel,将系统的其他推送设置为另一个Channel,这样用户就可以选择只接受哪一个通知,而不用像目前国产ROM一样,只能显示/隐藏整个应用的通知。
如果我们的Notification没有设置任何的Channel,那么在8.0上面是显示不出来的!会提示如下错误
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)
新建Channel
首先实例化一个NotificationChannel 对象,ChannelID是一个字符串,注意不要太长,不然可能会被系统截断,设置好Channel的相关属性以后,使用NotificationManager.createNotificationChannel即可创建好一个Channel,然后我们创建NotificationCompat.Builder的时候将ChannelId传入即可。
如下所示,我们需要判断Android版本,因为在8.0以下是没有NotificationChannel的,不然会导致crash。
String channelId = "通知渠道ID";
String channelName = "通知渠道名称";
String channelDescription = "通知渠道描述";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
channelName, NotificationManager.IMPORTANCE_DEFAULT);
channel.enableLights(true); //设置开启指示灯,如果设备有的话
channel.setLightColor(Color.RED); //设置指示灯颜色
channel.setShowBadge(true); //设置是否显示角标
channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);//设置是否应在锁定屏幕上显示此频道的通知
channel.setDescription(channelDescription);//设置渠道描述
channel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 600});//设置震动频率
channel.setBypassDnd(true);//设置是否绕过免打扰模式
//Android O上对Notification进行了修改,如果设置的targetSDKVersion>=26建议使用此种方式创建通知栏
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager != null) {
notificationManager.createNotificationChannel(channel);
}
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId);
builder.setSmallIcon()
.setContentTitle()
.setContentText()
.setWhen(System.currentTimeMillis());
builder.build();
PS:可以看到,这里使用的是NotificationCompat,这样可以提高兼容性。
获取所有Channel
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
List<NotificationChannel> list = mNotificationManager.getNotificationChannels();
}
获取指定Channel
//如果不存在返回null
mNotificationManager.getNotificationChannel(channelId)
删除Channel
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
mNotificationManager.deleteNotificationChannel("通知渠道ID");
}
跳转到通知渠道设置
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同样允许我们为几个Channel设置一个组,代码同样很简单。
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
mNotificationManager.createNotificationChannelGroup(new NotificationChannelGroup("通知渠道组ID", "通知渠道组名称"));
}
然后将Channel与渠道组相绑定。
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
channel.setGroup("通知渠道组ID");
}
8.0上通知不停震动以及响铃
NotificationChannel channel = new NotificationChannel(channelId,channelName, NotificationManager.IMPORTANCE_DEFAULT);
我们在创建NotificationChannel的时候使用的NotificationManager.IMPORTANCE_DEFAULT,这样系统会响铃以及震动,我们可以设置为NotificationManager.IMPORTANCE_LOW