通知

創(chuàng)建一個基本的通知

以最基本和緊湊形式(也稱為折疊形式)的通知顯示圖標,標題和少量內(nèi)容文本。在本節(jié)中,您將學(xué)習如何創(chuàng)建用戶可以點擊的通知來在應(yīng)用中啟動活動。

圖1. 帶有標題和文本的通知

有關(guān)通知各部分的更多詳細信息,請閱讀有關(guān) 通知解剖的內(nèi)容

設(shè)置通知內(nèi)容

要開始使用,您需要使用[NotificationCompat.Builder]對象設(shè)置通知的內(nèi)容和頻道 。以下示例顯示如何使用以下命令創(chuàng)建通知:

  • 一個小圖標,[setSmallIcon()]。這是唯一需要的用戶可見內(nèi)容。
  • 標題,[setContentTitle()]
  • 正文,[setContentText()]
  • 通知優(yōu)先級,由...設(shè)定[setPriority()]。優(yōu)先級決定了Android 7.1及更低版本的通知應(yīng)具有多大的侵入性。(對于Android 8.0及更高版本,您必須設(shè)置頻道重要性 - 如下一節(jié)所示。)
NotificationCompat.Builder mBuilder =  new  NotificationCompat.Builder(this, CHANNEL_ID)  .setSmallIcon(R.drawable.notification_icon)  
.setContentTitle(textTitle)  
.setContentText(textContent) 
.setPriority(NotificationCompat.PRIORITY_DEFAULT);

注意[NotificationCompat.Builder]構(gòu)造函數(shù)要求你提供一個通道ID。這是與Android 8.0(API級別26)及更高版本兼容所必需的,但舊版本會忽略它。

默認情況下,通知的文本內(nèi)容被截斷以適合一行。如果您希望通知時間更長,可以通過添加樣式模板來啟用可擴展通知[setStyle()]。例如,下面的代碼創(chuàng)建一個更大的文本區(qū)域:

NotificationCompat.Builder mBuilder = 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);

有關(guān)其他大型通知樣式的更多信息,包括如何添加圖像和媒體播放控件,請參閱使用展開式詳細信息創(chuàng)建通知

創(chuàng)建一個頻道并設(shè)置重要性

在Android 8.0及更高版本上發(fā)布通知之前,您必須向系統(tǒng)注冊您的應(yīng)用程序的 [通知渠道],方法是[NotificationChannel]向其 傳遞實例[createNotificationChannel()]。因此,以下代碼被[SDK_INT]版本中的條件阻止 :

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    // Create the NotificationChannel, but only on API 26+ because
    // the NotificationChannel class is new and not in the support library
    CharSequence name = getString(R.string.channel_name);
    String description = getString(R.string.channel_description);
    int importance = NotificationManagerCompat.IMPORTANCE_DEFAULT;
    NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
    channel.setDescription(description);
    // Register the channel with the system
    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
    notificationManager.createNotificationChannel(channel);
}

注意[NotificationChannel]構(gòu)造函數(shù)需要importance使用類中的一個常量[NotificationManagerCompat]。此參數(shù)確定如何中斷用戶對屬于此的任何通知信道,雖然必須同時設(shè)置的優(yōu)先級[setPriority()]支持Android 7.1和下(如上所示)。

盡管您必須如此處所示設(shè)置通知重要性/優(yōu)先級,但系統(tǒng)并不保證您會收到警報行為。在某些情況下,系統(tǒng)可能會根據(jù)其他因素改變重要性級別,用戶可以隨時重新定義給定頻道的重要性級別。

有關(guān)不同級別的含義的更多信息,請閱讀有關(guān)通知重要性級別
。

設(shè)置通知的點按操作

每個通知都應(yīng)該對點擊進行響應(yīng),通常會在您的應(yīng)用中打開與通知相對應(yīng)的活動。為此,您必須指定一個用[PendingIntent]對象定義的內(nèi)容意圖并將其傳遞給[setContentIntent()]。

以下片段顯示了如何在用戶點擊通知時創(chuàng)建打開活動的基本意圖:

// 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, 0);

NotificationCompat.Builder mBuilder = 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 will fire when the user taps the notification
        .setContentIntent(pendingIntent)
        .setAutoCancel(true);

注意這個代碼調(diào)用[setAutoCancel()], 當用戶點擊它時[會]自動[刪除通知]。

[setFlags()]上面顯示的方法有助于在通過通知打開您的應(yīng)用程序后保留用戶的預(yù)期導(dǎo)航體驗。但是,您是否想要使用這取決于您開始的活動類型,可能是以下某種活動:

· 專門用于響應(yīng)通知的活動。在正常的應(yīng)用程序使用過程中,用戶無需導(dǎo)航到此活動,因此該活動將啟動一項新任務(wù),而不是添加到您的應(yīng)用程序的現(xiàn)有 [任務(wù)和后退堆棧中]。這是上面示例中創(chuàng)建的意圖類型。

· 存在于您應(yīng)用的常規(guī)應(yīng)用流中的活動。在這種情況下,啟動該活動應(yīng)創(chuàng)建一個后退堆棧,以便保留用戶對Back和Up按鈕的期望。

有關(guān)配置通知意圖的不同方法的更多信息,請參閱從通知開始活動
。

顯示通知

要顯示通知,請調(diào)用[NotificationManagerCompat.notify()]并為其傳遞一個唯一的通知ID和結(jié)果[NotificationCompat.Builder.build()]。例如:

NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);

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

請記住保存您傳遞給的通知ID,[NotificationManagerCompat.notify()]因為如果您想[更新]或[刪除通知],以后需要它 。

注意:從Android 8.1(API級別27)開始,應(yīng)用程序無法每秒發(fā)出一次以上的通知聲音。如果您的應(yīng)用在一秒內(nèi)發(fā)布多個通知,它們?nèi)及搭A(yù)期顯示,但每秒只有第一個通知發(fā)出聲音。

添加操作按鈕

通知最多可以提供三個操作按鈕,以便用戶快速響應(yīng),例如暫停提醒或甚至回復(fù)短信。但是這些操作按鈕不應(yīng)復(fù)制用戶[點擊通知]時執(zhí)行的操作 。

圖2. 帶有一個動作按鈕的的通知

添加動作按鈕,傳遞[PendingIntent][addAction()]方法。這就像設(shè)置通知的默認點按操作一樣,除了啟動活動之外,您還可以執(zhí)行其他各種操作,例如啟動[BroadcastReceiver]在后臺執(zhí)行作業(yè)的操作,以便操作不會中斷已打開的應(yīng)用程序。

例如,以下代碼顯示如何將廣播發(fā)送到特定接收者:

 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 mBuilder = 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);

有關(guān)構(gòu)建[BroadcastReceiver](https://developer.android.com/reference/android/content/BroadcastReceiver.html) 要運行后臺工作的更多信息,請參閱 廣播指南

如果您嘗試使用媒體播放按鈕(例如暫停和跳過曲目)來構(gòu)建通知,請參閱如何使用媒體控件創(chuàng)建通知

添加直接回復(fù)操作

Android 7.0(API級別24)中引入的直接回復(fù)操作允許用戶直接在通知中輸入文本,通知會在不打開任何活動的情況下發(fā)送到您的應(yīng)用。例如,您可以使用直接回復(fù)操作來讓用戶回復(fù)通知中的短信或更新任務(wù)列表。


圖3.點擊“Reply”按鈕打開文本輸入

直接回復(fù)操作在打開文本輸入的通知中顯示為附加按鈕。當用戶完成輸入時,系統(tǒng)將文本響應(yīng)附加到您為通知操作指定的意圖,并將意圖發(fā)送到您的應(yīng)用程序。

添加回復(fù)按鈕

創(chuàng)建支持直接回復(fù)的通知操作:

  1. 創(chuàng)建一個[RemoteInput.Builder] 可以添加到通知操作的實例。此類的構(gòu)造函數(shù)接受系統(tǒng)用作文本輸入的關(guān)鍵字的字符串。稍后,掌上電腦應(yīng)用程序會使用該鍵來檢索輸入的文本。
// 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. 創(chuàng)建一個[PendingIntent]回復(fù)操作。

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

警告:如果您重新使用[PendingIntent],用戶可能會回復(fù)與他們認為不同的對話。您必須為每個對話提供一個不同的請求代碼,或者提供一個true在您調(diào)用[equals()] 任何其他對話的回復(fù)意圖時不會返回的意圖。對話ID經(jīng)常作為意圖的額外套餐的一部分傳遞,但在您致電時會被忽略[equals()]

3 將該RemoteInput 對象附加到使用的操作 [addRemoteInput()]// 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. 將操作應(yīng)用于通知并發(fā)出通知。

// Build the notification and add the action.
Notification newMessageNotification = new Notification.Builder(mContext, 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);

系統(tǒng)提示用戶在觸發(fā)通知操作時輸入響應(yīng),如圖3所示。

從回復(fù)中檢索用戶輸入

從通知的答復(fù)UI,呼叫接收用戶輸入 [RemoteInput.getResultsFromIntent()],它傳遞[Intent]您收到的[BroadcastReceiver]

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

處理完文本后,您必須[NotificationManagerCompat.notify()](https://developer.android.com/reference/java/lang/Object.html#notify())使用相同的ID和標簽(如果使用)更新通知 。這對于隱藏直接回復(fù)UI并向用戶確認他們的回復(fù)已被正確接收和處理是必要的。

// 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()]方法的上下文。

您還應(yīng)該通過呼叫將答復(fù)追加到通知底部 [setRemoteInputHistory()]。但是,如果您正在構(gòu)建消息傳遞應(yīng)用程序,則應(yīng)該創(chuàng)建[消息傳遞式通知] 并將新消息附加到對話中。

有關(guān)消息應(yīng)用程序通知的更多建議,請參閱消息傳遞應(yīng)用程序的[最佳實踐]

添加一個進度條

通知可以包含一個動畫進度指示器,向用戶顯示正在進行的操作的狀態(tài)


圖4.操作期間和之后的進度條

如果您可以隨時估計完成的操作有多少,請使用指示器的“確定”形式(如圖4所示) [setProgress(max, progress, false)]。第一個參數(shù)是“完整”值(例如100); 第二個是當前完成的數(shù)量,最后一個表示這是確定的進度條。

隨著您的操作進行,持續(xù)呼叫[setProgress(max, progress, false)]更新后的值 progress并重新發(fā)出通知。

NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID);
mBuilder.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;
mBuilder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
notificationManager.notify(notificationId, mBuilder.build());

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

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

在手術(shù)結(jié)束時,progress應(yīng)該相等 max。您可以讓進度條顯示操作完成時間,或?qū)⑵鋭h除。無論哪種情況,請記住更新通知文本以顯示操作已完成。要刪除進度條,請致電[setProgress(0, 0, false)]

注意:由于進度條要求您的應(yīng)用程序不斷更新通知,因此此代碼通常應(yīng)在后臺服務(wù)中運行。

要顯示不確定的進度條(不指示完成百分比的欄),請調(diào)用 [setProgress(0, 0, true)]。結(jié)果是一個與上面的進度條具有相同樣式的指示符,除了進度條是一個不表示完成的連續(xù)動畫。進度動畫會一直運行,直到您致電 [setProgress(0, 0, false)] ,然后更新通知以刪除活動指示符。

請記住更改通知文本以表明操作已完成。

注意:如果您確實需要下載文件,您應(yīng)該考慮使用 [DownloadManager],它提供了自己的通知來跟蹤您的下載進度。

設(shè)置一個系統(tǒng)范圍的類別

Android使用某些預(yù)定義的系統(tǒng)范圍類別來確定當用戶啟用["請勿打擾”模式]時是否使用給定通知[打擾]用戶 。

如果您的通知屬于中定義的預(yù)先定義的通知類別之一[NotificationCompat]-如[CATEGORY_ALARM][CATEGORY_REMINDER], [CATEGORY_EVENT],或[CATEGORY_CALL]-你應(yīng)該通過合適的類別聲明它是這樣[setCategory()]。

NotificationCompat.Builder mBuilder = 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);

當設(shè)備處于免打擾模式時,系統(tǒng)將使用有關(guān)您的通知類別的這些信息來做出關(guān)于顯示通知的決定。

但是,您無需設(shè)置系統(tǒng)范圍的類別,只有在您的通知與由in定義的某個類別匹配時才應(yīng)該這樣做 [NotificationCompat](https://developer.android.com/reference/android/support/v4/app/NotificationCompat.html)。

設(shè)置鎖定屏幕可見性


要通過鎖定屏幕控制通知中可見的詳細程度,請調(diào)用[setVisibility()]并指定以下值之一:

· [VISIBILITY_PUBLIC] 顯示通知的完整內(nèi)容。

· [VISIBILITY_SECRET] 在鎖定屏幕上不顯示此通知的任何部分。

· [VISIBILITY_PRIVATE] 顯示基本信息,例如通知圖標和內(nèi)容標題,但隱藏通知的完整內(nèi)容。

何時[VISIBILITY_PRIVATE]設(shè)置,您還可以提供隱藏某些詳細信息的通知內(nèi)容的備用版本。例如,短信應(yīng)用可能會顯示一條通知,顯示您有3條新短信,但隱藏了短信內(nèi)容和發(fā)件人。要提供此替代通知,請首先[NotificationCompat.Builder]像往常一樣創(chuàng)建替代通知。然后用另外的通知附加替代通知[setPublicVersion()]。

但是,用戶始終可以最終控制他們的通知是否在鎖定屏幕上可見,甚至可以根據(jù)您的應(yīng)用程序的通知渠道來控制這些通知。

更新通知


要在發(fā)布通知后更新此通知,請[NotificationManagerCompat.notify()]再次撥打電話,并將與您先前使用的ID相同的通知傳遞給它。如果先前的通知已被解除,則會創(chuàng)建新的通知。

您可以選擇打電話, [setOnlyAlertOnce()]以便只在通知出現(xiàn)時通知才會中斷用戶(包括聲音,振動或視覺線索),而不是在以后進行更新。

警告:Android在更新通知時應(yīng)用速率限制。如果您過于頻繁地發(fā)布更新(通常少于一秒),系統(tǒng)可能會放棄一些更新。

刪除通知


通知保持可見,直到發(fā)生以下情況之一:

· 用戶關(guān)閉通知。

· 用戶單擊通知,并[setAutoCancel()]在創(chuàng)建通知時調(diào)用 。

· 你需要[cancel()]一個特定的通知ID。此方法還會刪除正在進行的通知。

· 你打電話[cancelAll()],這將刪除您先前發(fā)出的所有通知。

· 如果您在創(chuàng)建通知時設(shè)置超時 [setTimeoutAfter()],系統(tǒng)會在指定的持續(xù)時間過后取消通知。如果需要,您可以在超過指定的超時時間之前取消通知。

消息傳遞應(yīng)用的最佳實踐


使用此處列出的最佳做法作為創(chuàng)建消息傳遞和聊天應(yīng)用通知時要記住的內(nèi)容的快速參考。

使用MessagingStyle

從Android 7.0(API級別24)開始,Android為消息內(nèi)容專門提供通知樣式模板。使用該 [NotificationCompat.MessagingStyle] 課程,您可以更改通知中顯示的多個標簽,包括會話標題,其他消息和通知的內(nèi)容視圖。

以下代碼片段演示了如何使用MessagingStyle該類自定義通知的樣式。

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]該類的通知 將以折疊形式顯示更多內(nèi)容。您還可以使用該[addHistoricMessage()]方法通過向與消息傳遞相關(guān)的通知添加歷史消息來為對話提供上下文。

使用時[NotificationCompat.MessagingStyle]

· 呼叫[MessagingStyle.setConversationTitle()]為兩人以上的群組聊天設(shè)置標題。一個好的對話標題可能是群組聊天的名稱,或者如果它沒有特定的名稱,則可能是對話中的參與者列表。如果沒有這個,該消息可能被誤認為屬于與對話中最近消息的發(fā)送者的一對一對話。

· 使用該[MessagingStyle.setData()] 方法來包含媒體消息,如圖像。目前支持模式圖像/ *的MIME類型。

使用直接回復(fù)

直接回復(fù)允許用戶回復(fù)內(nèi)部消息。

· 用戶回復(fù)內(nèi)嵌回復(fù)操作后,用于 [MessagingStyle.addMessage()]更新 MessagingStyle通知,并且不收回或取消通知。不取消通知允許用戶從通知中發(fā)送多個回復(fù)。

· 要使內(nèi)聯(lián)回復(fù)操作與Android Wear兼容,請致電。[ Action.WearableExtender.setHintDisplayInlineAction(true)]

· 通過向通知添加歷史消息,使用該方法為直接回復(fù)對話提供上下文。[ addHistoricMessage()]

啟用智能回復(fù)

· 要啟用智能回復(fù),請調(diào)用回復(fù)操作。這會使通知橋接到Android Wear設(shè)備時,用戶可以使用智能回復(fù)響應(yīng)。智能回復(fù)響應(yīng)由完全在機器學(xué)習模型生成,使用 通知提供的上下文,并且沒有數(shù)據(jù)上傳到互聯(lián)網(wǎng)以生成響應(yīng)。[ setAllowGeneratedResponses(true)][NotificationCompat.MessagingStyle]

添加通知元數(shù)據(jù)

· 當設(shè)備處于免打擾模式時,分配通知元數(shù)據(jù)以告知系統(tǒng)如何處理您的應(yīng)用通知。例如,使用 or 方法覆蓋免打擾模式。 addPerson() setCategory(Notification.CATEGORY_MESSAGE)

本文源自 * 發(fā)展* 指南* 用戶界面和導(dǎo)航* 通知

2018/3/9

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容