8、通知优先级与震动:优先级(PRIORITY)与重要性(IMPORTANCE)的区别、自定义震动模式、LED灯颜色设置
通知的优先级和重要性,这两个概念我见过太多人搞混了。说白了,它们一个管的是显示效果,一个管的是系统行为。今天咱们就把这事彻底掰扯清楚。
8.1 优先级(PRIORITY) vs 重要性(IMPORTANCE)
先问个问题:你发一条通知,想让它在通知栏顶部显示,还是想让它在锁屏上弹出来?这两个需求,其实是两套系统在管。
8.1.1 优先级(PRIORITY)—— 老版本时代的产物
优先级是 Android 4.1 到 7.1 时代的概念。它控制的是通知在通知栏里的排序和视觉样式。我记得在 Android 5.0 的项目里,我们团队为了抢通知栏顶部位置,把优先级全设成了 MAX,结果用户反馈通知栏乱成一锅粥……
| 常量 | 值 | 说明 |
|---|---|---|
| PRIORITY_MIN | -2 | 最小优先级,折叠在底部 |
| PRIORITY_LOW | -1 | 低优先级,不显示在顶部 |
| PRIORITY_DEFAULT | 0 | 默认,按时间排序 |
| PRIORITY_HIGH | 1 | 高优先级,显示在顶部 |
| PRIORITY_MAX | 2 | 最高优先级,强制置顶 |
setPriority() 方法已被标记为废弃。你仍然可以调用它,但系统会忽略这个值,转而使用通知渠道的 IMPORTANCE 设置。
8.1.2 重要性(IMPORTANCE)—— 渠道时代的核心
重要性是 Android 8.0 引入通知渠道后,用来替代优先级的机制。它决定了通知能不能弹出、会不会响、要不要震动。我个人习惯把重要性理解为「系统对这条通知的重视程度」。
| 常量 | 值 | 行为表现 |
|---|---|---|
| IMPORTANCE_NONE | 0 | 不显示通知,完全静默 |
| IMPORTANCE_MIN | 1 | 显示在通知栏底部,无声音无震动 |
| IMPORTANCE_LOW | 2 | 显示在通知栏,无声音但有状态栏图标 |
| IMPORTANCE_DEFAULT | 3 | 有声音,有震动,弹出通知 |
| IMPORTANCE_HIGH | 4 | 有声音,有震动,弹出通知,可显示在锁屏 |
| IMPORTANCE_MAX | 5 | 同 HIGH,但允许使用全屏意图 |
8.2 自定义震动模式
震动模式这事,我在做即时通讯 App 时踩过坑。当时产品要求「不同联系人用不同震动」,我直接用 Vibrator 写死了模式,结果发现通知的震动和系统震动是两套机制。
8.2.1 使用 NotificationCompat 设置震动
通知的震动模式通过 setVibrate() 方法设置,参数是一个 long 数组。数组的规则是:奇数位是震动时长,偶数位是停顿时长,单位都是毫秒。
// 震动模式:震动200ms,停100ms,震动200ms,停100ms,震动400ms
long[] vibratePattern = new long[]{0, 200, 100, 200, 100, 400};
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("新消息")
.setContentText("你有一条紧急消息")
.setVibrate(vibratePattern)
.setDefaults(Notification.DEFAULT_SOUND); // 注意:不要同时设置 DEFAULT_VIBRATE
new long[]{500, 200, 300} 表示先停 500ms,再震 200ms,再停 300ms。
8.2.2 渠道级别的震动设置
在 Android 8.0 以上,震动模式需要在创建通知渠道时指定。注意:渠道创建后震动模式不可修改,除非用户手动更改系统设置。
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID,
"紧急消息",
NotificationManager.IMPORTANCE_HIGH
);
// 设置渠道级别的震动模式
long[] vibratePattern = new long[]{0, 300, 200, 300};
channel.setVibrationPattern(vibratePattern);
// 启用震动
channel.enableVibration(true);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
enableVibration(true) 和 setVibrate() 同时使用,系统会优先使用渠道的震动模式。但如果你在 NotificationCompat.Builder 中又调用了 setDefaults(Notification.DEFAULT_VIBRATE),那就会覆盖渠道设置。嗯,这里要特别注意。
8.3 LED 灯颜色设置
LED 灯这事,说实话现在的新手机越来越少见了。但如果你在做一些工业级 App 或者对老机型有兼容需求,这个功能还是很有用的。
8.3.1 设置 LED 灯颜色
LED 灯颜色通过 setLights() 方法设置,需要三个参数:颜色值、亮灯时长、灭灯时长。
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("系统警告")
.setContentText("电池电量低于20%")
// 红色LED,亮500ms,灭500ms
.setLights(Color.RED, 500, 500)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
8.3.2 渠道级别的 LED 设置
同样,在 Android 8.0 以上,LED 灯颜色也可以在渠道中设置:
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID,
"系统警告",
NotificationManager.IMPORTANCE_HIGH
);
// 设置LED灯颜色为红色
channel.setLightColor(Color.RED);
channel.enableLights(true);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
8.4 知识体系总览
下面这张图把优先级、重要性、震动和 LED 灯的关系梳理清楚了。你一看就明白:
8.5 实战建议
最后给几个我自己的经验:
- 别混用优先级和重要性:如果你还在用
setPriority(),赶紧迁移到通知渠道 +setImportance()。我见过一个项目两个都设了,结果测试时发现行为完全不可控。 - 震动模式别太复杂:长震动模式(超过 3 段)会让用户觉得手机坏了。我一般只用两段:
{0, 200, 100, 200}或者{0, 400}。 - LED 灯颜色别用纯白:白色 LED 在大多数手机上显示为微弱的光,几乎看不见。红色和蓝色最明显,绿色次之。
- 尊重用户设置:用户可以在系统设置里修改通知渠道的震动和 LED 灯。你的代码只是「建议」,不是「强制」。
嗯,优先级和重要性这块,说白了就是「旧的不去新的不来」。早点拥抱通知渠道,你的通知管理会省心很多。
公众号:蓝海资料掘金营,微信deep3321