Android 8.0 引入了通知渠道,其允许您为要显示的每种通知类型创建用户可自定义的渠道。用户界面将通知渠道称之为通知类别。targeSdk升级到26之后,所有的通知的实现都需要提供通知渠道,如果不提供通知渠道的话,所有通知在8.0系统上面都不能正常展示,下面来看代码。
既然是兼容,当然不能少了判断系统版本了:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 大于等于 8.0 系统版本
}else { // 低于8.0 版本
}
针对8.0以上的版本 注意 创建 NotificationChannel , 并设置其创建同一 channelId,注意 这个id不能过长, 过长可能被截断;
private final String NOTIFICATION_CHANNEL_NAME = "Service";
private final String NOTIFICATION_DESCRIPTION = "读取位置信息";
private NotificationManager notificationManager = null;
private NotificationChannel notificationChannel = null;
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//Android O上对Notification进行了修改,如果设置的targetSDKVersion>=26建议使用此种方式创建通知栏
if (null == notificationManager) {
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
String channelId = "channel";
if (notificationChannel == null) {
notificationChannel = new NotificationChannel(channelId,
NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
notificationChannel.setDescription(NOTIFICATION_DESCRIPTION);
// 设置通知出现时的闪灯(如果 android 设备支持的话)
notificationChannel.enableLights(true);
notificationChannel.setLightColor(0);
notificationManager.createNotificationChannel(notificationChannel);
}
mBuilder.setChannel(channelId);
}
mBuilder.setPriority(0);// 设置该通知优先级
mBuilder.setSmallIcon(R.mipmap.logo);
mBuilder.setContentTitle(getString(R.string.app_name));
mBuilder.setContentText(getString(R.string.app_runing));
mBuilder.setContentIntent(intent);
notification = mBuilder.build();
startForeground(ServiceID.ID, notification);
在这里 我所兼容的8.0以上机型, 通过这样设置channel 还是会弹出 错误信息:“Failed to post notification on channel "null"”;
这里都是通过 v7包下的 NotificationCompat 创建,怎么还会报错并且报错 指代的是 notification on channel null????
于是我们这样更新一下代码,针对8.0的 做另一种设置 channel方式:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//Android O上对Notification进行了修改,如果设置的targetSDKVersion>=26建议使用此种方式创建通知栏
if (null == notificationManager) {
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
String channelId = "channel";
if (notificationChannel == null) {
notificationChannel = new NotificationChannel(channelId,
NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
notificationChannel.setDescription(NOTIFICATION_DESCRIPTION);
// 设置通知出现时的闪灯(如果 android 设备支持的话)
notificationChannel.enableLights(true);
notificationChannel.setLightColor(0);
notificationManager.createNotificationChannel(notificationChannel);
}
// 这里 针对8.0 我们如下设置 channel
notification = new Notification.Builder(this.getApplicationContext(),channelId)
.setSmallIcon(R.mipmap.logo)
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.app_runing)).build();
}else {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
mBuilder.setPriority(0);// 设置该通知优先级
mBuilder.setSmallIcon(R.mipmap.logo);
mBuilder.setContentTitle(getString(R.string.app_name));
mBuilder.setContentText(getString(R.string.app_runing));
notification = mBuilder.build();
}
startForeground(ServiceID.ID, notification);
因为跟很多帖子描述的问题不同,在此记录让大家参考一下。 8.0一下 通过 NotificationCompat 设置, 8.0以及以上 通过Notification 设置, 然后大家也发现 Notification 在 8.0 以后 废弃了 一个参数的构造方法, 取代的就是多了一个 channel 的构造方法。