创建和管理通知渠道

从 Android 8.0(API 级别 26)开始,所有通知都必须分配到一个渠道。对于每个渠道,您可以设置应用于该渠道中所有通知的视觉和听觉行为。用户可以更改这些设置并决定您的应用中的哪些通知渠道可能是侵入性的或可见的。

查看以下视频,了解 Android 8.0 中的渠道和其他通知功能概述。

每个应用的系统设置中都提供了通知渠道的用户设置,如图 1 所示。

图 1. 时钟应用及其其中一个渠道的通知设置。

创建通知渠道后,您无法更改通知行为。此时,用户拥有完全控制权。但是,您仍然可以更改渠道的名称和描述。

为需要发送的每种类型的通知创建一个渠道。您还可以创建通知渠道来反映用户做出的选择。例如,您可以为消息应用中用户创建的每个对话组设置单独的通知渠道。

当您以 Android 8.0(API 级别 26)或更高版本为目标时,必须实现一个或多个通知渠道。如果您的 targetSdkVersion 设置为 25 或更低版本,则当您的应用在 Android 8.0(API 级别 26)或更高版本上运行时,其行为与在运行 Android 7.1(API 级别 25)或更低版本的设备上的行为相同。

创建通知渠道

要创建通知渠道,请按照以下步骤操作

  1. 使用唯一的渠道 ID、用户可见的名称和重要性级别构造 NotificationChannel 对象。

  2. 可选地,使用 setDescription() 指定用户在系统设置中看到的描述。

  3. 通过将其传递给 createNotificationChannel() 来注册通知渠道。

以下示例显示了如何创建和注册通知渠道

Kotlin

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    // Create the NotificationChannel.
    val name = getString(R.string.channel_name)
    val descriptionText = getString(R.string.channel_description)
    val importance = NotificationManager.IMPORTANCE_DEFAULT
    val mChannel = NotificationChannel(CHANNEL_ID, name, importance)
    mChannel.description = descriptionText
    // Register the channel with the system. You can't change the importance
    // or other notification behaviors after this.
    val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
    notificationManager.createNotificationChannel(mChannel)
}

Java

private void createNotificationChannel() {
    // Create the NotificationChannel, but only on API 26+ because
    // the NotificationChannel class is 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);
    }
}

使用其原始值重新创建现有通知渠道不会执行任何操作,因此在启动应用时安全地调用此代码。

默认情况下,发布到给定渠道的所有通知都使用 NotificationManagerCompat 类中重要性级别定义的视觉和听觉行为,例如 IMPORTANCE_DEFAULTIMPORTANCE_HIGH。有关 重要性级别 的更多信息,请参见下一节。

如果要进一步自定义渠道的默认通知行为,可以在 NotificationChannel 上调用 enableLights()setLightColor()setVibrationPattern() 等方法。请记住,创建渠道后,您无法更改这些设置,并且用户最终可以控制这些行为是否处于活动状态。

您还可以通过调用 createNotificationChannels() 在单个操作中创建多个通知渠道。

设置重要性级别

渠道重要性会影响在渠道中发布的所有通知的中断级别。在 NotificationChannel 构造函数中指定它,使用五个重要性级别之一,范围从 IMPORTANCE_NONE(0)IMPORTANCE_HIGH(4)

要支持运行 Android 7.1(API 级别 25)或更低版本的设备,您还必须为每个通知调用 setPriority(),使用 NotificationCompat 类中的优先级常量。

重要性(NotificationManager.IMPORTANCE_*)和优先级(NotificationCompat.PRIORITY_*)常量映射到用户可见的重要性选项,如下表所示。

用户可见的重要性级别 重要性(Android 8.0 及更高版本) 优先级(Android 7.1 及更低版本)
紧急
发出声音并显示为抬头通知。
IMPORTANCE_HIGH PRIORITY_HIGHPRIORITY_MAX

发出声音。
IMPORTANCE_DEFAULT PRIORITY_DEFAULT

不发出声音。
IMPORTANCE_LOW PRIORITY_LOW

不发出声音,也不出现在状态栏中。
IMPORTANCE_MIN PRIORITY_MIN

不发出声音,也不出现在状态栏或阴影中。
IMPORTANCE_NONE N/A

所有通知,无论其重要性如何,都显示在非中断系统 UI 位置,例如通知抽屉和 启动器图标上的徽章,尽管您可以 修改通知徽章的外观

将渠道提交到 NotificationManager 后,您无法更改重要性级别。但是,用户可以随时更改其应用渠道的偏好设置。

有关选择适当优先级级别的信息,请参见 通知设计指南 中的“优先级级别”。

读取通知渠道设置

用户可以修改通知渠道的设置,包括振动和警报声等行为。如果要了解用户应用于通知渠道的设置,请按照以下步骤操作

  1. 通过调用 getNotificationChannel()getNotificationChannels() 获取 NotificationChannel 对象。

  2. 查询特定渠道设置,例如 getVibrationPattern()getSound()getImportance()

如果您检测到您认为会抑制应用预期行为的渠道设置,则可以建议用户更改它并提供一个操作以打开渠道设置,如下一节所示。

打开通知渠道设置

创建通知渠道后,您无法以编程方式更改通知渠道的视觉和听觉行为。只有用户才能从系统设置中更改渠道行为。要为您的用户提供轻松访问这些通知设置的途径,请在应用的 设置 UI 中添加一个项目以打开这些系统设置。

您可以使用使用 ACTION_CHANNEL_NOTIFICATION_SETTINGS 操作的 Intent 打开通知渠道的系统设置。

例如,以下示例代码显示了如何将用户重定向到通知渠道的设置

Kotlin

val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS).apply {
    putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
    putExtra(Settings.EXTRA_CHANNEL_ID, myNotificationChannel.getId())
}
startActivity(intent)

Java

Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
intent.putExtra(Settings.EXTRA_CHANNEL_ID, myNotificationChannel.getId());
startActivity(intent);

请注意,该意图需要两个额外信息,这些信息指定了应用的包名称(也称为应用 ID)和要编辑的渠道。

删除通知渠道

您可以通过调用 deleteNotificationChannel() 删除通知渠道。以下示例代码演示了如何完成此过程

Kotlin

// The id of the channel.
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val id: String = "my_channel_01"
notificationManager.deleteNotificationChannel(id)

Java

NotificationManager notificationManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// The id of the channel.
String id = "my_channel_01";
notificationManager.deleteNotificationChannel(id);

创建通知渠道组

如果您希望在设置 UI 中进一步组织渠道的外观,可以创建渠道组。当您的应用支持多个用户帐户(例如工作配置文件)时,这是一个好主意,因为它允许您为每个帐户创建一个通知渠道组。这样,用户可以轻松识别和控制具有相同名称的多个通知渠道。

图 2. 个人和工作帐户的通知渠道设置(含组)。

例如,一个社交网络应用程序可能包含对个人和工作帐户的支持。在这种情况下,每个帐户可能需要多个具有相同功能和名称的通知渠道,例如以下情况:

  • 个人帐户有两个渠道

    • 新评论

    • 帖子推荐

  • 企业帐户有两个渠道

    • 新评论

    • 帖子推荐

将通知渠道组织到每个帐户的组中,使用户能够区分它们。

每个通知渠道组都需要一个 ID,该 ID 必须在您的包中唯一,以及一个用户可见的名称。以下代码片段演示了如何创建通知渠道组。

Kotlin

// The id of the group.
val groupId = "my_group_01"
// The user-visible name of the group.
val groupName = getString(R.string.group_name)
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannelGroup(NotificationChannelGroup(groupId, groupName))

Java

// The id of the group.
String groupId = "my_group_01";
// The user-visible name of the group.
CharSequence groupName = getString(R.string.group_name);
NotificationManager notificationManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannelGroup(new NotificationChannelGroup(groupId, groupName));

创建新组后,您可以调用 setGroup() 将新的 NotificationChannel 对象与该组关联。

提交渠道到通知管理器后,您无法更改通知渠道和组之间的关联。