建立通知

通知功能可在應用程式處於閒置狀態時,提供簡短且即時的應用程式事件資訊。本文件說明如何建立包含各種功能的通知。如要瞭解通知在 Android 上的顯示方式,請參閱「通知總覽」。如需使用通知的程式碼範例,請參閱 GitHub 上的人物範例

本頁的程式碼使用 AndroidX 程式庫的 NotificationCompat API。這些 API 可讓您新增只能在較新版本 Android 上使用的功能,同時仍提供與 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")
}

建立基本通知

最基本和精簡形式的通知 (也稱為「收合表單」) 會顯示圖示、標題和少量文字內容。本節將說明如何建立通知,讓使用者輕觸通知來啟動應用程式中的活動。

圖 1 包含圖示、標題和一些文字的通知。

如要進一步瞭解通知的各個部分,請參閱通知分析

設定通知內容

如要開始使用,請使用 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);

如要進一步瞭解其他大型通知樣式,包括如何新增圖片和媒體播放控制項,請參閱「建立展開式通知」。

建立管道並設定重要性

在 Android 8.0 以上版本中傳送通知之前,請將 NotificationChannel 的執行個體傳遞至 createNotificationChannel(),以向系統註冊應用程式的通知管道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() 將「Priority」設為支援 Android 7.1 以下版本,如上述範例所示。

雖然您必須依照以下範例設定通知重要性或優先順序,但系統無法保證您收到的快訊行為。在某些情況下,系統可能會根據其他因素變更重要性等級,使用者隨時可以重新定義特定管道的重要性等級。

如要進一步瞭解不同層級代表的意義,請參閱通知重要性等級

設定通知的輕觸動作

每則通知都必須回應輕觸操作,通常用於開啟與通知對應的應用程式活動。方法是指定使用 PendingIntent 物件定義的內容意圖,並傳遞至 setContentIntent()

以下程式碼片段說明如何建立在使用者輕觸通知時開啟活動的基本意圖:

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() 方法可在使用者透過通知開啟應用程式後,保留預期的導航體驗。建議您根據要開始的活動類型使用它,可能是下列其中一種:

  • 專門用於回應通知的活動。使用者在一般應用程式使用期間不必前往這個活動,因此活動會啟動新工作,而不是新增到應用程式的現有的任務和返回堆疊中。這是在上述範例中建立的意圖類型。

  • 應用程式一般應用程式流程中的活動。在這種情況下,系統會在活動啟動時建立返回堆疊,以便保留使用者對「返回」和「向上」按鈕的期望。

如要進一步瞭解設定通知意圖的各種方式,請參閱從通知啟動活動

顯示通知

如要顯示通知,請呼叫 NotificationManagerCompat.notify(),並向其傳遞通知的專屬 ID,以及 NotificationCompat.Builder.build() 的結果。例如:

Kotlin

with(NotificationManagerCompat.from(this)) {
    // notificationId is a unique int for each notification that you must define.
    notify(notificationId, builder.build())
}

Java

NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);

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

儲存傳遞至 NotificationManagerCompat.notify() 的通知 ID,因為在您要更新移除通知時將會用到。

新增動作按鈕

通知最多可提供三個動作按鈕,讓使用者快速回應,例如延後提醒或回覆簡訊。但使用者輕觸通知時,這些動作按鈕不得重複執行的操作。

圖 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) 中導入的直接回覆動作可讓使用者直接在通知中輸入文字。文字隨後會傳送至您的應用程式,無須開啟活動。舉例來說,您可以使用直接回覆動作,讓使用者透過通知回覆簡訊或更新工作清單。

圖 4. 輕觸「回覆」按鈕可開啟文字輸入內容。

在開啟文字輸入的通知中,直接回覆動作會顯示為額外的按鈕。使用者輸入完成後,系統會將文字回應附加至您為通知動作指定的意圖,並將意圖傳送至應用程式。

新增回覆按鈕

如要建立支援直接回覆的通知動作,請按照下列步驟操作:

  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. 使用 addRemoteInput()RemoteInput 物件附加至動作。

    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 所示。

從回覆中擷取使用者輸入內容

如要從通知的回覆 UI 接收使用者輸入內容,請呼叫 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(),藉此更新通知。您必須隱藏直接回覆 UI,並讓使用者確認已收到並正確處理他們的回覆。

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. 作業期間的進度列。

如果您可以預估作業要隨時完成,請使用指標的「終止」形式 (如圖 5 所示),方法是呼叫 setProgress(max, progress, false)。第一個參數是「完整」值,例如 100。第二點是已完成一半。最後一種表示這是已確定的進度列。

作業繼續進行時,請持續呼叫 setProgress(max, progress, false)progress 值,然後重新發出通知,如以下範例所示。

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),然後更新通知以移除活動指標為止。

請記得變更通知文字,以表示作業已完成。

設定系統通用類別

使用者啟用「零打擾」模式時,Android 會使用預先定義的系統通用類別,判斷是否要向使用者傳送指定的通知。

如果您的通知屬於 NotificationCompat 中定義的其中一個通知類別,例如 CATEGORY_ALARMCATEGORY_REMINDERCATEGORY_EVENTCATEGORY_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 定義的其中一個類別時,才能執行這項操作。

顯示緊急訊息

您的應用程式可能需要顯示緊急且具時效性的訊息,例如來電或鈴聲鬧鐘。在這種情況下,您可以將全螢幕意圖與通知建立關聯。

叫用通知時,使用者會根據裝置的鎖定狀態顯示下列其中一種內容:

  • 如果使用者的裝置處於鎖定狀態,系統會顯示全螢幕活動,並在螢幕鎖定狀態下顯示活動。
  • 如果使用者的裝置處於解鎖狀態,通知便會以展開形式顯示,其中包含處理或關閉通知的選項。

下列程式碼片段說明如何建立通知與全螢幕意圖的關聯:

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_PUBLIC:在螢幕鎖定畫面上顯示通知的完整內容。

  • VISIBILITY_SECRET:螢幕鎖定畫面不會顯示任何通知。

  • VISIBILITY_PRIVATE:螢幕鎖定畫面只會顯示基本資訊,例如通知的圖示和內容標題。不會顯示通知的完整內容。

設定 VISIBILITY_PRIVATE 時,您也可以提供替代版本的通知內容來隱藏特定詳細資料。例如,簡訊應用程式可能會顯示「您有 3 則新簡訊」通知,但隱藏訊息內容和寄件者。如要提供此替代通知,請先照常使用 NotificationCompat.Builder 建立替代通知。接著,使用 setPublicVersion() 將替代通知附加到一般通知中。

請注意,使用者隨時可以控制是否要讓通知顯示在螢幕鎖定畫面中,並根據應用程式的通知管道加以控制。

更新通知

如要在發出後更新通知,請再次呼叫 NotificationManagerCompat.notify(),並傳遞您先前使用的 ID。如果關閉上一則通知,則系統會改為建立新通知。

您可以選擇呼叫 setOnlyAlertOnce(),讓通知幹擾使用者 (包括音效、震動或視覺線索),只在第一次顯示通知時而不進行更新。

移除通知

只要發生下列其中一種情況,通知就會持續顯示:

  • 使用者關閉通知。
  • 如果您在建立通知時呼叫了 setAutoCancel(),使用者就可以輕觸通知。
  • 您可以針對特定通知 ID 呼叫 cancel()。這個方法也會刪除進行中的通知。
  • 呼叫 cancelAll(),這會移除您先前發出的所有通知。
  • 如果您在建立通知時設定了逾時,使用 setTimeoutAfter() 便會經過指定的時間長度。如有需要,您可以在指定的逾時時間過後取消通知。

訊息應用程式的最佳做法

為訊息和即時通訊應用程式建立通知時,請考慮此處列出的最佳做法。

使用 MessagingStyle

從 Android 7.0 (API 級別 24) 開始,Android 提供了適用於訊息內容的通知樣式範本。您可以使用 NotificationCompat.MessagingStyle 類別變更通知上顯示的多個標籤,包括對話標題、其他訊息,以及通知的內容檢視畫面。

下列程式碼片段示範如何使用 MessagingStyle 類別自訂通知的樣式。

Kotlin

var notification = NotificationCompat.Builder(this, CHANNEL_ID)
        .setStyle(NotificationCompat.MessagingStyle("Me")
                .setConversationTitle("Team lunch")
                .addMessage("Hi", timestamp1, null) // Pass in null for user.
                .addMessage("What's up?", timestamp2, "Coworker")
                .addMessage("Not much", timestamp3, null)
                .addMessage("How about lunch?", timestamp4, "Coworker"))
        .build()

Java

Notification notification = new Notification.Builder(this, CHANNEL_ID)
        .setStyle(new NotificationCompat.MessagingStyle("Me")
                .setConversationTitle("Team lunch")
                .addMessage("Hi", timestamp1, null) // Pass in null for user.
                .addMessage("What's up?", timestamp2, "Coworker")
                .addMessage("Not much", timestamp3, null)
                .addMessage("How about lunch?", timestamp4, "Coworker"))
        .build();

從 Android 8.0 (API 級別 26) 開始,使用 NotificationCompat.MessagingStyle 類別的通知會在收合表單中顯示更多內容。您也可以使用 addHistoricMessage() 方法,在訊息相關通知中加入過往訊息,提供對話的背景資訊。

使用 NotificationCompat.MessagingStyle 時,請執行下列操作:

  • 呼叫 MessagingStyle.setConversationTitle() 為兩人以上的群組通訊設定標題。理想的對話標題可能是群組通訊的名稱,如果沒有名稱,則可能是對話的參與者清單。如果沒有這麼做,訊息可能會誤認為對話中最新訊息的寄件者是一對一的對話。
  • 如要加入媒體訊息 (例如圖片),請使用 MessagingStyle.setData() 方法。模式圖片/* 的 MIME 類型。

使用直接回覆功能

「直接回覆」功能可讓使用者在郵件中直接回覆郵件。

啟用智慧回覆

  • 如要啟用智慧回覆功能,請在回覆動作中呼叫 setAllowGeneratedResponses(true)。這樣一來,在通知橋接到 Wear OS 裝置時,使用者就能存取智慧回覆。智慧回覆回應是由完全觀看影片的機器學習模型產生,該模型會使用 NotificationCompat.MessagingStyle 通知提供的情境資訊,且沒有任何資料上傳到網際網路以產生回應。

新增通知中繼資料