通知渠道配置:重要性等级、声音、震动、锁屏可见性、自定义设置

3.1 原理:通知渠道的五大配置维度

Android 8.0(API 26)引入通知渠道(NotificationChannel)机制,将通知按类别分组,每个渠道独立控制用户感知行为。用户可对每个渠道单独调整通知行为,系统据此决定是否显示、如何提醒。核心配置包括:

维度属性字段影响范围
重要性等级importance决定打断级别(弹窗、声音、状态栏图标)
声音sound通知到达时的音频提示
震动vibrationPattern / enableVibration触觉反馈模式
锁屏可见性lockscreenVisibility通知在锁屏上的显示级别(全部/部分/隐藏)
自定义设置setBypassDnd / setLightColor / setShowBadge 等免打扰、LED灯色、角标等扩展行为

重要原则:渠道创建后,importance、sound、vibrationPattern、lockscreenVisibility 等核心属性不可被应用代码修改(用户可手动覆盖)。因此首次创建时必须谨慎配置。

3.2 实现流程图:渠道配置决策路径

通知渠道配置决策流程图 1. 确定渠道用途 2. 选择重要性等级 (IMPORTANCE_*) 3. 配置 声音URI / 震动模式 / 震动开关 Uri soundUri = RingtoneManager.getDefaultUri(...) 4. 设置锁屏可见性 (VISIBILITY_*) 5. 自定义:免打扰绕过/角标/LED颜色 6. 注册渠道 (createNotificationChannel) 创建后重要性/声音/震动/锁屏可见性无法修改;需要新渠道需使用新ID。

3.3 实现流程:代码级配置

3.3.1 创建渠道(Kotlin)

// 定义渠道 ID 和名称
val CHANNEL_ID_ALERTS = "alerts"
val CHANNEL_NAME = "重要警报"
val CHANNEL_DESC = "系统关键警告,请勿关闭"

// 构建渠道对象(API 26+)
val channel = NotificationChannel(
    CHANNEL_ID_ALERTS,
    CHANNEL_NAME,
    NotificationManager.IMPORTANCE_HIGH  // 重要性等级
)
channel.description = CHANNEL_DESC

// 声音:使用系统默认消息铃声
val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
channel.setSound(soundUri, Notification.AUDIO_ATTRIBUTES_DEFAULT)

// 震动:自定义模式 [等待, 震动, 等待, 震动...](单位毫秒)
channel.enableVibration(true)
channel.vibrationPattern = longArrayOf(0, 300, 200, 300)

// 锁屏可见性:显示全部内容
channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC

// 自定义:允许免打扰时发出声音
channel.setBypassDnd(true)

// 角标显示
channel.setShowBadge(true)

// 注册渠道
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)

3.3.2 不同重要性等级的行为对比

常量数值用户可见行为典型场景
IMPORTANCE_NONE0无通知(静默丢弃)废弃渠道
IMPORTANCE_MIN1无声音,不显示状态栏图标,下拉通知栏可见后台同步提示
IMPORTANCE_LOW2无声音,显示状态栏图标普通信息
IMPORTANCE_DEFAULT3有声音,弹出通知,显示图标标准消息
IMPORTANCE_HIGH4有声音,浮动通知(Heads-up),屏幕唤醒紧急警报
IMPORTANCE_MAX5同 HIGH,但部分厂商可自定义更高优先级系统级警告

3.4 调试与验证

3.4.1 ADB 命令查看渠道列表

# 列出指定包名下的所有通知渠道
adb shell dumpsys notification --package com.your.app | grep "Channel"
调试技巧:使用 adb shell dumpsys notification 可看到每个渠道的 importance、sound、vibration、lockscreenVisibility 当前值。

3.4.2 手动覆盖测试

在设置 → 通知 → 应用 → 渠道名称 中手动修改渠道属性,然后发送通知验证应用是否会正确读取用户覆盖值。注意:应用代码无法再读取用户修改后的值,只能通过系统 API 查询渠道配置。

// 查询渠道当前用户设置(包括用户手动调整)
val currentChannel = notificationManager.getNotificationChannel(CHANNEL_ID_ALERTS)
Log.d("Channel", "importance: ${currentChannel.importance}")
Log.d("Channel", "sound: ${currentChannel.sound}")
Log.d("Channel", "lockscreen: ${currentChannel.lockscreenVisibility}")

3.5 常见错误与避免

  • 运行时修改核心属性:渠道创建后调用 setSound()、setVibrationPattern() 等不会产生效果。必须创建新渠道(使用新 ID)或删除旧渠道重新创建。
  • 未处理 Android 8.0 以下兼容:低于 API 26 的设备需通过 NotificationCompat.Builder.setPriority() 控制,但渠道本身不存在。需判断 SDK 版本。
  • 震动权限:VIBRATE 权限需要在 Manifest 中声明。
  • 声音 URI 无效:sound 设为 null 会使用默认声音;设为无效 URI 可能导致通知无声。

3.6 性能与稳定性优化

  • 渠道数量限制:每个应用最多可创建约 50 个渠道(厂商可能更少)。按功能模块创建,避免为每一个通知实例创建单独的渠道。
  • 渠道复用:相同重要程度和行为的通知使用同一渠道,减少用户设置负担。
  • 预创建策略:在应用首次启动时一次性创建所有渠道,避免运行时频繁创建。
注意:在 Android 13+(API 33+)中,发送通知需要运行时权限 POST_NOTIFICATIONS。渠道创建本身不需要权限,但用户拒绝后通知不会送达。建议在创建渠道后再请求通知权限。