android 8.0通知新增了NotificationChannel(通知渠道),用来帮助管理用户通知。Android Studio新版会默认使用新版本的SDK编译项目,如果App的targetSDKVersion >=26或者Android Studio默认使用高于26的sdk作为targetSDK时,没有使用NotificationChannel就会出现在Android 8.0及以上系统通知无法展示的情况。
Android O 引入了 通知渠道(Notification Channels),以提供统一的系统来帮助用户管理通知,如果是针对 android O 为目标平台时,必须实现一个或者多个通知渠道,以向用户显示通知。比如聊天软件,为每个聊天组设置一个通知渠道,指定特定声音、灯光等配置。
创建NotificationChannel对象时,除了构造方法里面的参数,其余参数是可选的,如果不设置会使用系统默认的,且部分参数因为手机厂商不同,可能没有效果比如设置桌面Launcher消息角标
public static String CALENDAR_ID = "channel_01";
private static Notification createNotification(Context context, NotificationManager notificationManager) {
Notification notification;NotificationCompat.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(CALENDAR_ID, "123",
NotificationManager.IMPORTANCE_DEFAULT);
// 设置渠道描述
notificationChannel.setDescription("测试通知组");
// 是否绕过请勿打扰模式
notificationChannel.canBypassDnd();
// 设置绕过请勿打扰模式
notificationChannel.setBypassDnd(true);
// 桌面Launcher的消息角标
notificationChannel.canShowBadge();
// 设置显示桌面Launcher的消息角标
notificationChannel.setShowBadge(true);
// 设置通知出现时声音,默认通知是有声音的
notificationChannel.setSound(null, null);
// 设置通知出现时的闪灯(如果 android 设备支持的话)
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
// 设置通知出现时的震动(如果 android 设备支持的话)
notificationChannel.enableVibration(true);
notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400,
300, 200, 400});
notificationManager.createNotificationChannel(notificationChannel);
}
builder = new NotificationCompat.Builder(context, CALENDAR_ID);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 11,
new Intent(context, SecondActivity.class), 0);
notification = builder.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentIntent(pendingIntent)
// .setChannelId(CALENDAR_ID)
.build();
return notification;
}
PS:推荐使用v4包下面的``NotificationCompat.Builder来创建Notification,兼容性和新特性都能使用到,创建Notification.Builder
的时候推荐使用双参数的构造方法 Builder(@NonNull Context context, @NonNull String channelId)
,单参数的构造方法已经被弃用,可能会因为没有配置ChannelId导致通知发送失败,即网上有的开发者说的Android 8.0通知不显示的问题
Tips:Android 8.0通知不显示大概率是因为没有配置ChannelId
Android8.0以后的版本,通知要显示除了要配置ChannelId
,还在系统中注册应用的通知渠道(NotificationChanne)
,可以在原来的通知生成之前加入以下代码:
private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = getString(R.string.channel_name);
String description = getString(R.string.channel_description);
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
需要注意的是ChannelId
和后面NotificationCompat.Builder
中的值保持一致,方法里面判断了Android 8.0及以上才会向系统注册通知渠道(NotificationChanne)
Tips:Android 9.0以及以后版本通知不显示大概率是向系统注册通知渠道(NotificationChanne)
通知的重要级别在Android 8.0 上下的设置方式、命名和值都不一样,比如同样是DEFAULT,Android 8.0里面是IMPORTANCE_DEFAULT,值是3
,Android 7.0里面是PRIORITY_DEFAULT,值是0
;
Android 7.0设置方法
builder.setPriority(NotificationCompat.PRIORITY_DEFAULT);
Android 8.0是通过NotificationChannel构造方法传入
NotificationChannel notificationChannel = new NotificationChannel(CALENDAR_ID, "123",
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(notificationChannel);
下面通过表格说明Android 8.0及以上与Android 8.0以下的通知用户级别的关系
用户通知级别 | Android 8.0及以上 | Android 7.0及以下 |
---|---|---|
紧急级别(发出通知声音并显示为提示通知) | IMPORTANCE_HIGH | PRIORITY_HIGH或者PRIORITY_MAX |
高级别(发出通知声音并且通知栏有通知 | IMPORTANCE_DEFAULT | PRIORITY_DEFAULT |
中等级别(没有通知声音但通知栏有通知) | IMPORTANCE_LOW | PRIORITY_LOW |
低级别(没有通知声音也不会出现在状态栏上) | IMPORTANCE_MIN | PRIORITY_MIN |
根据表格显示,级别是高级及以上级别时,系统是会发出声音的,不管你有没有设置提示语音。
参考链接:Android O(8.0) Notification解决方案