创建通知

通知可在应用期间提供有关应用内事件的简短、及时信息, 它未在使用中。本文档介绍了如何使用 各种功能有关通知在 Android 上的显示方式的介绍, 请参阅通知概览。 有关使用通知的示例代码,请参阅用户 示例

此页面中的代码使用 NotificationCompat AndroidX 库中的 API。借助这些 API,您可以添加 同时仍提供与 Android 兼容的功能 9(API 级别 28)。不过,部分功能(如内嵌回复操作) 会导致早期版本上出现空操作。

添加 AndroidX 核心库

尽管使用 Android Studio 创建的大多数项目都包含必要的 依赖项使用 NotificationCompat,请验证您的模块级 build.gradle 文件包含以下依赖项:

Groovy

dependencies {
    implementation "androidx.core:core:2.2.0"
}

Kotlin

dependencies {
    implementation("androidx.core:core-ktx:2.2.0")
}

创建基本通知

最基本和紧凑形式的通知,也称为收起状态通知 form - 显示图标、标题和少量文本内容。这个 部分展示了如何创建用户可点按以启动 activity。

图 1. 带有图标、标题和一些文本的通知。

有关通知的各个部分的详情,请参阅通知 剖析

声明运行时权限

Android 13(API 级别 33)及更高版本支持用于从应用发布非豁免(包括前台服务 [FGS])通知的运行时权限。

需要在应用的清单文件中声明的权限会显示在以下代码段中:

<manifest ...>
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <application ...>
        ...
    </application>
</manifest>

如需详细了解运行时权限,请参阅通知运行时权限

设置通知内容

首先,使用 NotificationCompat.Builder 对象。以下示例展示了如何创建带有 以下:

  • 小图标,通过 setSmallIcon() 设置。这是所必需的唯一用户可见内容。

  • 标题,由 setContentTitle() 设置。

  • 正文文本,由 setContentText()

  • 通知优先级,通过 setPriority() 设置。优先级决定了通知在 Android 7.1 和 。对于 Android 8.0 及更高版本,请将渠道重要性设置为 如下一部分所示。

Kotlin

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle(textTitle)
        .setContentText(textContent)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)

Java

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle(textTitle)
        .setContentText(textContent)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);

NotificationCompat.Builder 构造函数要求您提供频道 ID。这是与 Android 8.0(API 级别 26)和 但会被早期版本忽略。

默认情况下,通知的文本内容会被截断以放在一行。您 可以通过创建展开式通知来显示更多信息。

图 2. 展开式通知的收起和展开形式。

如果您想要更长的通知,可以使用 setStyle() 添加样式模板来启用可展开的通知。例如,以下代码可创建一个更大的文本区域:

Kotlin

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Much longer text that cannot fit one line...")
        .setStyle(NotificationCompat.BigTextStyle()
                .bigText("Much longer text that cannot fit one line..."))
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)

Java

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Much longer text that cannot fit one line...")
        .setStyle(new NotificationCompat.BigTextStyle()
                .bigText("Much longer text that cannot fit one line..."))
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);

如需详细了解其他大型通知样式,包括如何添加 图片和媒体播放控件,请参阅制作展开式 通知

创建渠道并设置重要性

您必须先注册您的 应用的通知渠道 方法是向系统传递 NotificationChannelcreateNotificationChannel()。 以下代码会被 SDK_INT 版本:

Kotlin

private fun 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) {
        val name = getString(R.string.channel_name)
        val descriptionText = getString(R.string.channel_description)
        val importance = NotificationManager.IMPORTANCE_DEFAULT
        val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
            description = descriptionText
        }
        // Register the channel with the system.
        val notificationManager: NotificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    }
}

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);
    }
}

由于您必须先创建通知渠道,然后才能在 Android 8.0 及更高版本上发布任何通知,因此请在应用启动时立即执行这段代码。您可以反复调用它,因为要创建一个现有的 不会执行任何操作。

NotificationChannel 构造函数需要一个 importance,使用其中一个 常量(从 NotificationManager 类。这个 参数确定如何针对任何属于 此频道。使用 setPriority() 设置优先级,以支持 Android 7.1 如前面的示例所示

尽管您必须按 例如,系统无法保证您所收到的提醒行为。在 在某些情况下,系统可能会根据其他因素更改重要性级别, 而且用户可以随时重新定义给定项目的重要程度 。

如需详细了解不同级别的含义,请参阅 通知的重要性 级别

设置通知的点按操作

每条通知都必须响应点按操作,通常是在 Google Play 应用中打开 activity 应用。为此,请指定内容 intent 使用 PendingIntent 定义 对象并将其传递给 setContentIntent()

以下代码段展示了如何创建用于打开 activity 的基本 intent 当用户点按通知时触发:

Kotlin

// Create an explicit intent for an Activity in your app.
val intent = Intent(this, AlertDetails::class.java).apply {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)

val builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        // Set the intent that fires when the user taps the notification.
        .setContentIntent(pendingIntent)
        .setAutoCancel(true)

Java

// Create an explicit intent for an Activity in your app.
Intent intent = new Intent(this, AlertDetails.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        // Set the intent that fires when the user taps the notification.
        .setContentIntent(pendingIntent)
        .setAutoCancel(true);

此代码会调用 setAutoCancel()、 在用户点按通知时自动移除通知

setFlags() 方法 保留了用户的预期导航 提供更优质的体验你可能需要 根据你要启动的 activity 类型(可以是 以下:

  • 专用于响应通知的 activity。 用户在正常使用应用时可以无缘无故导航到此 activity, 因此该 activity 会启动一个新任务,而不是添加到应用的 现有任务,然后返回 堆栈。这是 上述示例中创建的 intent 类型。

  • 应用的常规应用流程中存在的 Activity。在此示例中 启动 activity 会创建一个返回堆栈,满足用户的预期 返回和向上按钮的按钮 保留。

如需详细了解配置通知 intent 的不同方法,请参阅 从通知启动 Activity

显示通知

要显示通知,请调用 NotificationManagerCompat.notify()、 向它传递通知的唯一 ID 以及 NotificationCompat.Builder.build()。 具体可见以下示例:

Kotlin

with(NotificationManagerCompat.from(this)) {
    if (ActivityCompat.checkSelfPermission(
            this@MainActivity,
            Manifest.permission.POST_NOTIFICATIONS
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        // TODO: Consider calling
        // ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        // public fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>,
        //                                        grantResults: IntArray)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.

        return@with
    }
    // notificationId is a unique int for each notification that you must define.
    notify(NOTIFICATION_ID, builder.build())
}

Java

with(NotificationManagerCompat.from(this)) {
   if (ActivityCompat.checkSelfPermission(
           this@MainActivity,
           Manifest.permission.POST_NOTIFICATIONS
       ) != PackageManager.PERMISSION_GRANTED
   ) {
       // TODO: Consider calling
       // ActivityCompat#requestPermissions
       // here to request the missing permissions, and then overriding
       // public void onRequestPermissionsResult(int requestCode, String[] permissions,
       //                                        int[] grantResults)
       // to handle the case where the user grants the permission. See the documentation
       // for ActivityCompat#requestPermissions for more details.

       return
   }
   // notificationId is a unique int for each notification that you must define.
   notify(NOTIFICATION_ID, builder.build())
}

请保存您传递给 NotificationManagerCompat.notify() 的通知 ID,因为如果您想要更新移除通知,将需要使用这个 ID。

此外,为了在运行 对于 Android 13 及更高版本,请手动开启通知或创建一个对话框 请求通知。

添加操作按钮

一个通知最多可以提供三个操作按钮,让用户可以快速响应,例如暂停提醒或回复短信。但这些 操作按钮不得重复用户点按 通知

图 3. 显示以下内容的通知: 一个操作按钮。

如需添加操作按钮,请将 PendingIntent 传递给 addAction() 方法。这与设置通知的默认点按操作类似,只不过 您可以执行其他一些操作,例如启动一个 BroadcastReceiver 在后台执行作业,以免操作中断应用 这个已经打开的对象

例如,以下代码展示了如何将广播发送到特定的 接收器:

Kotlin


val ACTION_SNOOZE = "snooze"

val snoozeIntent = Intent(this, MyBroadcastReceiver::class.java).apply {
    action = ACTION_SNOOZE
    putExtra(EXTRA_NOTIFICATION_ID, 0)
}
val snoozePendingIntent: PendingIntent =
    PendingIntent.getBroadcast(this, 0, snoozeIntent, 0)
val builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent)

Java


String ACTION_SNOOZE = "snooze"

Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class);
snoozeIntent.setAction(ACTION_SNOOZE);
snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0);
PendingIntent snoozePendingIntent =
        PendingIntent.getBroadcast(this, 0, snoozeIntent, 0);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent);

详细了解如何构建 BroadcastReceiver 以运行后台 请参阅广播概览

如果您尝试构建包含媒体播放按钮的通知, 例如,暂停和跳过曲目,请参阅如何创建带有媒体的通知 控件

添加直接回复操作

Android 7.0(API 级别 24)中引入的直接回复操作可让用户 直接在通知中输入文字随后,系统会将该文本发送到您的 而无需打开 activity。例如,您可以使用直接回复操作 可让用户从 通知。

图 4. 点按“回复”按钮会打开文本输入框。

直接回复操作以附加按钮的形式显示在通知中, 打开文本输入。当用户完成输入后,系统会将文本 为通知操作指定的 intent 的响应,并将 intent。

添加回复按钮

如需创建支持直接回复的通知操作,请按以下步骤操作:

  1. 创建 RemoteInput.Builder 您可以将其添加到通知操作中。此类的构造函数接受 一个字符串,系统将其用作文本输入的键。稍后安装您的应用 使用该键检索输入的文本。

    Kotlin

      // Key for the string that's delivered in the action's intent.
      private val KEY_TEXT_REPLY = "key_text_reply"
      var replyLabel: String = resources.getString(R.string.reply_label)
      var remoteInput: RemoteInput = RemoteInput.Builder(KEY_TEXT_REPLY).run {
          setLabel(replyLabel)
          build()
      }
      

    Java

      // Key for the string that's delivered in the action's intent.
      private static final String KEY_TEXT_REPLY = "key_text_reply";
    
      String replyLabel = getResources().getString(R.string.reply_label);
      RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
              .setLabel(replyLabel)
              .build();
      
  2. 为回复操作创建 PendingIntent

    Kotlin

      // Build a PendingIntent for the reply action to trigger.
      var replyPendingIntent: PendingIntent =
          PendingIntent.getBroadcast(applicationContext,
              conversation.getConversationId(),
              getMessageReplyIntent(conversation.getConversationId()),
              PendingIntent.FLAG_UPDATE_CURRENT)
      

    Java

      // Build a PendingIntent for the reply action to trigger.
      PendingIntent replyPendingIntent =
              PendingIntent.getBroadcast(getApplicationContext(),
                      conversation.getConversationId(),
                      getMessageReplyIntent(conversation.getConversationId()),
                      PendingIntent.FLAG_UPDATE_CURRENT);
      
  3. RemoteInput 使用 addRemoteInput()

    Kotlin

      // Create the reply action and add the remote input.
      var action: NotificationCompat.Action =
          NotificationCompat.Action.Builder(R.drawable.ic_reply_icon,
              getString(R.string.label), replyPendingIntent)
              .addRemoteInput(remoteInput)
              .build()
      

    Java

      // Create the reply action and add the remote input.
      NotificationCompat.Action action =
              new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon,
                      getString(R.string.label), replyPendingIntent)
                      .addRemoteInput(remoteInput)
                      .build();
      
  4. 对通知应用操作并发出通知。

    Kotlin

      // Build the notification and add the action.
      val newMessageNotification = Notification.Builder(context, CHANNEL_ID)
              .setSmallIcon(R.drawable.ic_message)
              .setContentTitle(getString(R.string.title))
              .setContentText(getString(R.string.content))
              .addAction(action)
              .build()
    
      // Issue the notification.
      with(NotificationManagerCompat.from(this)) {
          notificationManager.notify(notificationId, newMessageNotification)
      }
      

    Java

      // Build the notification and add the action.
      Notification newMessageNotification = new Notification.Builder(context, CHANNEL_ID)
              .setSmallIcon(R.drawable.ic_message)
              .setContentTitle(getString(R.string.title))
              .setContentText(getString(R.string.content))
              .addAction(action)
              .build();
    
      // Issue the notification.
      NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
      notificationManager.notify(notificationId, newMessageNotification);
      

当用户触发 如图 4 所示。

从回复中检索用户输入

要从通知的回复界面接收用户输入,请调用 RemoteInput.getResultsFromIntent()、 将 BroadcastReceiver 收到的 Intent 传递给它:

Kotlin

private fun getMessageText(intent: Intent): CharSequence? {
    return RemoteInput.getResultsFromIntent(intent)?.getCharSequence(KEY_TEXT_REPLY)
}

Java

private CharSequence getMessageText(Intent intent) {
    Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
    if (remoteInput != null) {
        return remoteInput.getCharSequence(KEY_TEXT_REPLY);
    }
    return null;
 }

处理完文本后,请调用 具有相同 ID 和标记(如果使用)的 NotificationManagerCompat.notify()。若要隐藏直接回复界面并向用户确认他们的回复已收到并得到正确处理,则必须完成该操作。

Kotlin

// Build a new notification, which informs the user that the system
// handled their interaction with the previous notification.
val repliedNotification = Notification.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.ic_message)
        .setContentText(getString(R.string.replied))
        .build()

// Issue the new notification.
NotificationManagerCompat.from(this).apply {
    notificationManager.notify(notificationId, repliedNotification)
}

Java

// Build a new notification, which informs the user that the system
// handled their interaction with the previous notification.
Notification repliedNotification = new Notification.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.ic_message)
        .setContentText(getString(R.string.replied))
        .build();

// Issue the new notification.
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(notificationId, repliedNotification);

在处理这个新通知时,请使用传递给 接收者的 onReceive() 方法。

通过调用 setRemoteInputHistory() 将回复附加到通知底部。但是,如果您要构建短信应用,则应创建短信式 通知,并将 向会话中发送一条新消息。

如需有关即时通讯应用通知的更多建议,请参阅有关即时通讯应用的最佳做法部分。

添加进度条

通知可以包含动画形式的进度指示器,向用户显示正在进行的操作的状态。

图 5. 进度条 操作。

如果您可以估算操作在任何时间点的完成进度,应通过调用 setProgress(max, progress, false) 使用指示器的“确定性”形式(如图 5 所示)。第一个参数是“完成”值,例如 100。第二个是完成了多少。最后一个表示 。

随着操作的继续,持续使用更新后的 progress 值调用 setProgress(max, progress, false),并重新发出通知,如下所示: 如以下示例中所示。

Kotlin

val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {
    setContentTitle("Picture Download")
    setContentText("Download in progress")
    setSmallIcon(R.drawable.ic_notification)
    setPriority(NotificationCompat.PRIORITY_LOW)
}
val PROGRESS_MAX = 100
val PROGRESS_CURRENT = 0
NotificationManagerCompat.from(this).apply {
    // Issue the initial notification with zero progress.
    builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false)
    notify(notificationId, builder.build())

    // Do the job that tracks the progress here.
    // Usually, this is in a worker thread.
    // To show progress, update PROGRESS_CURRENT and update the notification with:
    // builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
    // notificationManager.notify(notificationId, builder.build());

    // When done, update the notification once more to remove the progress bar.
    builder.setContentText("Download complete")
            .setProgress(0, 0, false)
    notify(notificationId, builder.build())
}

Java

...
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.setContentTitle("Picture Download")
        .setContentText("Download in progress")
        .setSmallIcon(R.drawable.ic_notification)
        .setPriority(NotificationCompat.PRIORITY_LOW);

// Issue the initial notification with zero progress.
int PROGRESS_MAX = 100;
int PROGRESS_CURRENT = 0;
builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
notificationManager.notify(notificationId, builder.build());

// Do the job that tracks the progress here.
// Usually, this is in a worker thread.
// To show progress, update PROGRESS_CURRENT and update the notification with:
// builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
// notificationManager.notify(notificationId, builder.build());

// When done, update the notification once more to remove the progress bar.
builder.setContentText("Download complete")
        .setProgress(0,0,false);
notificationManager.notify(notificationId, builder.build());

操作结束时,progress 必须等于 max。您可以离开 显示操作已完成或将其移除。无论哪种情况,都请更新通知文本,显示操作已完成。移除 进度条,调用 setProgress(0, 0, false)

显示不确定性进度条(不指示完成情况的进度条) 百分比),调用 setProgress(0, 0, true)。结果会产生一个与上一个进度条样式相同的指示器,区别是这个指示器是一个不指示完成情况的持续动画。在您调用 setProgress(0, 0, false) 之前,进度动画会一直运行,调用后系统会更新通知以移除 activity 指示器。

请务必更改通知文本,以表明操作 。

设置系统范围的类别

Android 使用预定义的系统范围类别来确定是否打扰 当用户启用勿扰模式时收到给定通知的用户 模式

如果您的通知属于 NotificationCompat,例如 CATEGORY_ALARM, CATEGORY_REMINDER, CATEGORY_EVENT, 或 CATEGORY_CALL - 声明 将相应的类别传递给 setCategory()

Kotlin

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setCategory(NotificationCompat.CATEGORY_MESSAGE)

Java

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setCategory(NotificationCompat.CATEGORY_MESSAGE);

系统会根据这些有关通知类别的信息 关于在设备处于“请勿”状态时显示通知的决策 打扰。不过,您无需设置系统级类别。请仅执行此操作 如果您的通知符合 NotificationCompat

显示紧急消息

您的应用可能需要显示紧急的时效性消息,例如来电或响铃警报。在这种情况下,您可以将 全屏 intent。

调用通知时,用户会看到以下某一项,具体取决于 设备的锁定状态:

  • 如果用户的设备被锁定,则系统会显示全屏 activity,覆盖 锁屏。
  • 如果用户设备处于解锁状态,通知以展开形式显示,其中包含用于处理或关闭通知的选项。

以下代码段演示了如何将通知与 全屏 intent:

Kotlin

val fullScreenIntent = Intent(this, ImportantActivity::class.java)
val fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
    fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT)

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setFullScreenIntent(fullScreenPendingIntent, true)

Java

Intent fullScreenIntent = new Intent(this, ImportantActivity.class);
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
        fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setFullScreenIntent(fullScreenPendingIntent, true);

设置锁定屏幕公开范围

如需控制锁定屏幕上通知的可见详细程度, 致电 setVisibility() 并指定以下某个值:

设置 VISIBILITY_PRIVATE 时,您还可以提供 隐藏了某些详细信息的通知内容。例如,短信应用 系统可能会显示“您有 3 条新短信”的通知但是 会隐藏邮件内容和发件人。如需提供此备用内容,请执行以下操作: 先创建备用通知, 像往常一样NotificationCompat.Builder。然后,附上备选通知 普通通知 setPublicVersion()

请注意,对于通知在锁定屏幕上是否可见,用户始终拥有最终控制权,甚至可以根据应用的通知渠道来控制公开范围。

更新通知

要在发出通知后对其进行更新,请调用 NotificationManagerCompat.notify(),并向其传递您使用的相同 ID 。如果之前的通知已被关闭,则系统会创建一个新通知。

您可以选择调用 setOnlyAlertOnce() 这样,您的通知就会以声音、振动或视觉的方式打断用户 线索 - 仅在相应通知首次显示时提供,以后不会 更新。

移除通知

除非发生以下情况之一,否则通知仍然可见:

  • 用户关闭通知。
  • 如果您拨打 setAutoCancel(),则用户点按通知。 创建通知
  • 您致电 cancel() 特定通知 ID。此方法还会删除当前通知。
  • 您调用了 cancelAll() 方法,该方法将移除之前发出的所有通知。
  • 如果您在创建 使用 setTimeoutAfter()。 如果需要,您可以在指定超时之前取消通知 。

有关即时通讯应用的最佳做法

为您的 消息和聊天应用。

使用 MessagingStyle

从 Android 7.0(API 级别 24)开始,Android 提供了通知样式 模板。使用 NotificationCompat.MessagingStyle 类,您可以更改在通知中显示的多个标签, 包括会话标题、其他邮件和 通知。

以下代码段演示了如何使用 MessagingStyle 类自定义通知的样式。

Kotlin

val user = Person.Builder()
    .setIcon(userIcon)
    .setName(userName)
    .build()

val notification = NotificationCompat.Builder(this, CHANNEL_ID)
    .setContentTitle("2 new messages with $sender")
    .setContentText(subject)
    .setSmallIcon(R.drawable.new_message)
    .setStyle(NotificationCompat.MessagingStyle(user)
        .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getPerson())
        .addMessage(messages[2].getText(), messages[2].getTime(), messages[2].getPerson())
    )
    .build()

Java

Person user = new Person.Builder()
    .setIcon(userIcon)
    .setName(userName)
    .build();

Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
    .setContentTitle("2 new messages with " + sender)
    .setContentText(subject)
    .setSmallIcon(R.drawable.new_message)
    .setStyle(new NotificationCompat.MessagingStyle(user)
        .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getPerson())
        .addMessage(messages[2].getText(), messages[2].getTime(), messages[2].getPerson())
    )
    .build();

从 Android 9.0(API 级别 28)开始,还必须使用 Person 类,才能以最佳方式呈现通知及其头像。

使用 NotificationCompat.MessagingStyle 时,请执行以下操作:

  • 致电 MessagingStyle.setConversationTitle() 为超过两个用户的群聊设置标题。一个好的会话标题可以是群聊名称,如果没有名称,可以是会话中的参与者列表。否则,消息可能会被误以为属于与会话中最近消息发送者的一对一会话。
  • 使用 MessagingStyle.setData() 方法包含图像等媒体消息。模式的 MIME 类型 image/*。

使用直接回复

直接回复允许用户以内嵌方式回复消息。

启用智能回复

  • 如需启用智能回复,请对回复操作调用 setAllowGeneratedResponses(true)。这样,智能回复响应就可以供 当用户通知桥接到 Wear OS 设备时。智能回复 由一个完全在手表上的机器学习模型生成, NotificationCompat.MessagingStyle 提供的上下文 且系统不会将任何数据上传到互联网来生成 响应。

添加通知元数据