Android官方文檔—User Interface(Notifications)

通知欄

通知是您可以在應用程序的普通UI之外向用戶顯示的消息。當您告訴系統發出通知時,它首先在通知區域中顯示爲圖標。要查看通知的詳細信息,用戶將打開通知抽屜。通知區域和通知抽屜都是系統控制的區域,用戶可以隨時查看。

圖1.通知區域中的通知。
圖2.通知抽屜中的通知。

注意:除非另有說明,否則本指南引用版本4支持庫中的NotificationCompat.Builder類。在Android 3.0(API級別11)中添加了Notification.Builder類。

設計注意事項


通知作爲Android用戶界面的重要組成部分,有自己的設計指南。 Android 5.0(API級別21)中引入的材料設計更改特別重要,您應該查看Material Design培訓以獲取更多信息。要了解如何設計通知及其交互,請閱讀通知設計指南。

創建通知


您可以在NotificationCompat.Builder對象中指定通知的UI信息和操作。要創建通知本身,請調用NotificationCompat.Builder.build(),它返回包含您的規範的Notification對象。要發出通知,請通過調用NotificationManager.notify()將Notification對象傳遞給系統。

必填通知內容

Notification對象必須包含以下內容:

  • 一個小圖標,由setSmallIcon()設置
  • 標題,由setContentTitle()設置
  • 詳細文本,由setContentText()設置

可選的通知內容和設置

所有其他通知設置和內容都是可選的。要了解有關它們的更多信息,請參閱NotificationCompat.Builder的參考文檔。

Notification actions

雖然它們是可選的,但您應該在通知中添加至少一個操作。操作允許用戶直接從通知轉到應用程序中的活動,在那裏他們可以查看一個或多個事件或進行進一步的工作。

通知可以提供多個操作。您應始終定義用戶單擊通知時觸發的操作;通常此操作會在您的應用程序中打開一個Activity。您還可以向通知添加按鈕,以執行其他操作,例如暫停警報或立即響應文本消息;從Android 4.1開始提供此功能。如果您使用其他操作按鈕,則還必須在應用中的“活動”中提供其功能;有關詳細信息,請參閱處理兼容性部分。

在通知內部,操作本身由PendingIntent定義,該PendingIntent包含在應用程序中啓動Activity的Intent。要將PendingIntent與手勢相關聯,請調用NotificationCompat.Builder的相應方法。例如,如果要在用戶單擊通知抽屜中的通知文本時啓動Activity,則通過調用setContentIntent()添加PendingIntent。

用戶單擊通知時啓動活動是最常見的操作方案。您還可以在用戶解除通知時啓動活動。在Android 4.1及更高版本中,您可以從操作按鈕啓動活動。要了解更多信息,請閱讀NotificationCompat.Builder的參考指南。

通知優先權

如果您願意,可以設置通知的優先級。優先級充當設備UI關於如何顯示通知的提示。要設置通知的優先級,請調用NotificationCompat.Builder.setPriority()並傳入其中一個NotificationCompat優先級常量。有五個優先級,從PRIORITY_MIN(-2)到PRIORITY_MAX(2);如果未設置,則優先級默認爲PRIORITY_DEFAULT(0)。

有關設置適當優先級的信息,請參閱“通知設計指南”中的“正確設置和管理通知優先級”。

創建簡單的通知

以下代碼段說明了一個簡單的通知,指定用戶單擊通知時要打開的活動。請注意,代碼創建了一個TaskStackBuilder對象,並使用它爲該操作創建PendingIntent。在啓動活動時保留導航部分中更詳細地解釋了此模式:

NotificationCompat.Builder mBuilder =
        new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!");
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, ResultActivity.class);

// The stack builder object will contain an artificial back stack for the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
        stackBuilder.getPendingIntent(
            0,
            PendingIntent.FLAG_UPDATE_CURRENT
        );
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(mId, mBuilder.build());

這樣。您的用戶現已收到通知。

將擴展布局應用於通知

要在展開視圖中顯示通知,請首先使用所需的常規視圖選項創建NotificationCompat.Builder對象。接下來,使用展開的佈局對象作爲參數調用Builder.setStyle()。

請記住,在Android 4.1之前的平臺上無法使用擴展通知。要了解如何處理Android 4.1和早期平臺的通知,請閱讀處理兼容性部分。

例如,以下代碼段演示瞭如何更改在上一個代碼段中創建的通知以使用展開的佈局:

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
    .setSmallIcon(R.drawable.notification_icon)
    .setContentTitle("Event tracker")
    .setContentText("Events received")
NotificationCompat.InboxStyle inboxStyle =
        new NotificationCompat.InboxStyle();
String[] events = new String[6];
// Sets a title for the Inbox in expanded layout
inboxStyle.setBigContentTitle("Event tracker details:");
...
// Moves events into the expanded layout
for (int i=0; i < events.length; i++) {

    inboxStyle.addLine(events[i]);
}
// Moves the expanded layout object into the notification object.
mBuilder.setStyle(inBoxStyle);
...
// Issue the notification here.

處理兼容性

並非所有通知功能都可用於特定版本,即使設置它們的方法位於支持庫類NotificationCompat.Builder中也是如此。例如,依賴於擴展通知的操作按鈕僅出現在Android 4.1及更高版本上,因爲擴展通知本身僅適用於Android 4.1及更高版本。

要確保最佳兼容性,請使用NotificationCompat及其子類(尤其是NotificationCompat.Builder)創建通知。此外,在實施通知時請遵循以下流程:

1.向所有用戶提供所有通知功能,無論他們使用何種版本。爲此,請驗證應用中的活動是否可以使用所有功能。您可能需要添加新的活動來執行此操作。

例如,如果要使用addAction()提供停止和啓動媒體播放的控件,請首先在應用程序的“活動”中實現此控件。

2.通過在用戶單擊通知時啓動,確保所有用戶都可以訪問“活動”中的功能。爲此,請爲活動創建PendingIntent。調用setContentIntent()將PendingIntent添加到通知中。

3.現在,將要使用的擴展通知功能添加到通知中。請記住,您添加的任何功能也必須在用戶單擊通知時啓動的活動中可用。

管理通知


當您需要爲同一類型的事件多次發出通知時,您應該避免發出全新的通知。相反,您應該考慮更新以前的通知,方法是更改​​某些值或添加它,或者兩者兼而有之。

例如,Gmail通過增加未讀郵件的數量以及向通知添加每封電子郵件的摘要來通知用戶新電子郵件已到達。這稱爲“堆疊”通知;它在Notifications Design指南中有更詳細的描述。

注意:此Gmail功能需要“收件箱”展開式佈局,這是擴展通知功能的一部分。

以下部分介紹瞭如何更新通知以及如何刪除通知。

更新通知

要設置通知以便更新,請通過調用NotificationManager.notify()向通知ID發出通知。要在發出通知後更新此通知,請更新或創建NotificationCompat.Builder對象,從中構建Notification對象,並使用先前使用的相同ID發出通知。如果先前的通知仍然可見,則系統會從Notification對象的內容中更新它。如果先前的通知已被取消,則會創建新通知。

以下代碼段演示了一個更新的通知,以反映已發生的事件數。它堆疊通知,顯示摘要:

mNotificationManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Sets an ID for the notification, so it can be updated
int notifyID = 1;
mNotifyBuilder = new NotificationCompat.Builder(this)
    .setContentTitle("New Message")
    .setContentText("You've received new messages.")
    .setSmallIcon(R.drawable.ic_notify_status)
numMessages = 0;
// Start of a loop that processes data and then notifies the user
...
    mNotifyBuilder.setContentText(currentText)
        .setNumber(++numMessages);
    // Because the ID remains unchanged, the existing notification is
    // updated.
    mNotificationManager.notify(
            notifyID,
            mNotifyBuilder.build());
...

刪除通知

在發生以下情況之一之前,通知仍然可見:

  • 用戶單獨或使用“全部清除”(如果可以清除通知)解除通知。
  • 用戶單擊通知,並在創建通知時調用setAutoCancel()。
  • 您可以爲特定通知ID調用cancel()。此方法還會刪除正在進行的通知。
  • 您調用cancelAll(),它會刪除您之前發出的所有通知。

回覆通知


從Android 7.0(API級別24)開始,用戶可以直接響應文本消息或從通知對話框中更新任務列表。在手持設備上,內聯回覆操作顯示爲通知中顯示的附加按鈕。當用戶通過鍵盤迴復時,系統會將文本響應附加到您爲通知操作指定的意圖,並將意圖發送到掌上電腦應用程序。

圖1.“回覆”操作按鈕。

添加內聯回覆操作

要創建支持直接回復的通知操作:

1.創建一個可以添加到通知操作的RemoteInput.Builder實例。此類的構造函數接受系統用作文本輸入鍵的字符串。稍後,您的掌上電腦應用程序使用該鍵來檢索輸入的文本。

// 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.使用addRemoteInput()將RemoteInput對象附加到操作。

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

3.將操作應用於通知併發出通知。

// Build the notification and add the action.
Notification newMessageNotification =
        new Notification.Builder(mContext)
                .setSmallIcon(R.drawable.ic_message)
                .setContentTitle(getString(R.string.title))
                .setContentText(getString(R.string.content))
                .addAction(action))
                .build();

// Issue the notification.
NotificationManager notificationManager =
        NotificationManager.from(mContext);
notificationManager.notify(notificationId, newMessageNotification);

系統會在用戶觸發通知操作時提示用戶輸入響應。

圖2.用戶從通知陰影中輸入文本。

從內聯回覆中檢索用戶輸入

要從通知界面接收用戶輸入您在回覆操作的意圖中聲明的活動:

1.通過將通知操作的intent作爲輸入參數傳遞來調用getResultsFromIntent()。此方法返回包含文本響應的Bundle。

Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);

2.使用結果鍵(提供給RemoteInput.Builder構造函數)查詢包。您可以通過創建方法來完成此過程並檢索輸入文本,如以下代碼段所示:

// Obtain the intent that started this activity by calling
// Activity.getIntent() and pass it into this method to
// get the associated string.

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

3.使用您爲先前通知提供的相同通知ID構建併發出另一個通知。進度指示器從通知界面中消失,以通知用戶成功回覆。使用此新通知時,請使用傳遞給接收方的onReceive()方法的上下文。

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

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

對於交互式應用程序(例如聊天),您可以在處理檢索到的文本時包含其他上下文。例如,這些應用可以顯示多行聊天記錄。當用戶通過RemoteInput響應時,您可以使用setRemoteInputHistory()方法更新回覆歷史記錄。

應用程序收到遠程輸入後,通知必須更新或取消。當用戶使用“直接回復”回覆遠程更新時,請勿取消通知。而是更新通知以顯示用戶的回覆。對於使用MessagingStyle的通知,您應該將回復添加爲最新消息。使用其他模板時,您可以將用戶的回覆附加到遠程輸入歷史記錄中。

捆綁通知


從Android 7.0(API級別24)開始,Android爲開發人員提供了一種表示通知隊列的新方法:捆綁通知。這類似於Android Wear中的Notification Stacks功能。例如,如果您的應用爲收到的消息創建通知,則當收到多條消息時,將通知捆綁在一起作爲一個組。您可以使用Builder.setGroup()方法捆綁類似的通知。

通知組對包含它的通知強加層次結構。該層次結構的頂部是一個父通知,顯示該組的摘要信息。用戶可以逐步擴展通知組,並且系統在用戶深入鑽取時顯示更多信息。當用戶展開捆綁包時,系統會顯示其所有子通知的更多信息;當用戶展開其中一個通知時,系統會顯示其整個內容。

圖3.用戶可以逐步擴展通知組。

注意:如果同一個應用程序發送四個或更多通知但未指定分組,系統會自動將它們分組在一起。

要了解如何向組添加通知,請參閱將每個通知添加到組。

捆綁通知的最佳做法

本節提供有關何時使用通知組而不是Android 6.0及以前版本中提供的InboxStyle通知的指南。

何時使用捆綁通知

僅當以下所有條件均適用於您的用例時,才應使用通知組:

  • 子通知是完整的通知,可以單獨顯示,而無需組摘要。
  • 單獨顯示兒童通知有一個好處。例如:

1.它們是可操作的,具有針對每個孩子的特定行動。

2.用戶想要閱讀的孩子有更多信息。

通知組的良好用例示例包括:顯示傳入消息列表的消息傳遞應用程序,或顯示已接收電子郵件列表的電子郵件應用程序。

優選單個通知的情況的示例包括來自單個人的單個消息,或單行文本項的列表表示。您可以使用(InboxStyle或BigTextStyle)來完成此任務。

顯示捆綁的通知

應用程序應始終發佈組摘要,即使該組僅包含一個子組。如果僅包含單個通知,系統將禁止摘要並直接顯示子通知。這確保了當用戶滑動羣組的孩子時系統可以提供一致的體驗。

展開通知

雖然系統通常將子通知顯示爲一個組,但您可以將它們設置爲臨時顯示爲擡頭通知。此功能特別有用,因爲它允許立即訪問最近的子項以及與之關聯的操作。

向後兼容性

自Android 5.0(API級別21)起,通知組和遠程輸入都是Notification API的一部分,以支持Android Wear設備。如果您已經使用這些API構建了通知,則必須採取的唯一操作是驗證應用程序行爲是否符合上述指南,並考慮實現setRemoteInputHistory()。

爲了支持向後兼容性,支持庫的NotificationCompat類提供了相同的API,允許您構建適用於低於5.0的Android版本(API級別21)的通知。在手持設備和平板電腦上,用戶只能看到摘要通知,因此應用程序仍應具有收件箱樣式或相應的通知代表,以表示該組的整個信息內容。由於Android Wear設備允許用戶甚至在較舊的平臺級別上查看所有子通知,因此無論API級別如何,都應構建子通知。

啓動活動時保留導航


從通知啓動活動時,您必須保留用戶的預期導航體驗。單擊“返回”應該讓用戶將應用程序的正常工作流程返回到主屏幕,單擊“最近”應將“活動”顯示爲單獨的任務。要保留導航體驗,您應該在新任務中啓動活動。如何設置PendingIntent以爲您提供新任務取決於您正在啓動的Activity的性質。有兩種一般情況:

Regular activity

您正在啓動一個Activity,它是應用程序正常工作流程的一部分。在這種情況下,設置PendingIntent以啓動一個新任務,併爲PendingIntent提供一個後備堆棧,以再現應用程序的正常Back行爲。

來自Gmail應用的通知證明了這一點。單擊單個電子郵件的通知時,您會看到郵件本身。觸摸返回會將您向後移動到Gmail主屏幕,就像您從主屏幕輸入Gmail而不是通過通知輸入Gmail一樣。

無論您在觸摸通知時所處的應用程序如何,都會發生這種情況。例如,如果您在Gmail中撰寫郵件,並且單擊了一封電子郵件的通知,則會立即轉到該電子郵件。觸摸返回會將您帶到收件箱,然後顯示主屏幕

Special activity

如果用戶從通知開始,則只會看到此活動。從某種意義上說,Activity通過提供難以在通知本身中顯示的信息來擴展通知。對於這種情況,設置PendingIntent以在新任務中啓動。但是,不需要創建後臺堆棧,因爲啓動的Activity不是應用程序活動流的一部分。單擊“返回”仍會將用戶帶到主屏幕。

設置常規活動PendingIntent

1.在清單中定義應用程序的活動層次結構。

a。添加對Android 4.0.3及更早版本的支持。爲此,請通過添加<meta-data>元素作爲<activity>的子元素來指定您啓動的Activity的父級。

對於此元素,請設置android:name =“android.support.PARENT_ACTIVITY”。設置android:value =“<parent_activity_name>”,其中<parent_activity_name>是父<activity>元素的android:name的值。有關示例,請參閱以下XML。

b.還添加對Android 4.1及更高版本的支持。爲此,請將android:parentActivityName屬性添加到您正在啓動的Activity的<activity>元素中。

最終的XML應如下所示:

<activity
    android:name=".MainActivity"
    android:label="@string/app_name" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity
    android:name=".ResultActivity"
    android:parentActivityName=".MainActivity">
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value=".MainActivity"/>
</activity>

2.根據啓動Activity的Intent創建一個後棧:

a.創建Intent以啓動Activity。

b.通過調用TaskStackBuilder.create()創建堆棧構建器。

c.通過調用addParentStack()將後棧添加到堆棧構建器。對於您在清單中定義的層次結構中的每個活動,後堆棧包含啓動活動的Intent對象。此方法還添加了在新任務中啓動堆棧的標誌。

注意:儘管addParentStack()的參數是對已啓動的Activity的引用,但方法調用不會添加啓動Activity的Intent。相反,這將在下一步中得到解決。

e.如果需要,可以通過調用TaskStackBuilder.editIntentAt()爲堆棧上的Intent對象添加參數。當用戶使用Back導航到目標Activity時,有時需要確保目標Activity顯示有意義的數據。

f.通過調用getPendingIntent()獲取此堆棧的PendingIntent。然後,您可以將此PendingIntent用作setContentIntent()的參數。

以下代碼段演示了該過程:

Intent resultIntent = new Intent(this, ResultActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent to the top of the stack
stackBuilder.addNextIntent(resultIntent);
// Gets a PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
        stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());

設置特殊活動PendingIntent

以下部分介紹如何設置特殊活動PendingIntent。

特殊的Activity不需要後臺堆棧,因此您不必在清單中定義其Activity層次結構,也不必調用addParentStack()來構建後臺堆棧。相反,使用清單設置Activity任務選項,並通過調用getActivity()創建PendingIntent:

1.在清單中,將以下屬性添加到Activity的<activity>元素

android:name="activityclass"

活動的完全限定類名。

android:taskAffinity=""

結合您在代碼中設置的FLAG_ACTIVITY_NEW_TASK標誌,這可確保此活動不會進入應用程序的默認任務。具有應用程序默認親緣關係的任何現有任務都不會受到影響。

android:excludeFromRecents="true"

從“最近”中排除新任務,以便用戶不會意外導航回到它。

此代碼段顯示了該元素:

<activity
    android:name=".ResultActivity"
...
    android:launchMode="singleTask"
    android:taskAffinity=""
    android:excludeFromRecents="true">
</activity>
...

2.構建併發布通知:

a.創建一個啓動Activity的Intent。

b.通過使用標誌FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_CLEAR_TASK調用setFlags(),將Activity設置爲在新的空任務中啓動。

c.設置Intent所需的任何其他選項。

d.通過調用getActivity()從Intent創建PendingIntent。然後,您可以將此PendingIntent用作setContentIntent()的參數。

以下代碼段演示了該過程:

// Instantiate a Builder object.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// Creates an Intent for the Activity
Intent notifyIntent =
        new Intent(this, ResultActivity.class);
// Sets the Activity to start in a new, empty task
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_CLEAR_TASK);
// Creates the PendingIntent
PendingIntent notifyPendingIntent =
        PendingIntent.getActivity(
        this,
        0,
        notifyIntent,
        PendingIntent.FLAG_UPDATE_CURRENT
);

// Puts the PendingIntent into the notification builder
builder.setContentIntent(notifyPendingIntent);
// Notifications are issued by sending them to the
// NotificationManager system service.
NotificationManager mNotificationManager =
    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Builds an anonymous Notification object from the builder, and
// passes it to the NotificationManager
mNotificationManager.notify(id, builder.build());

顯示通知中的進度


通知可以包括動畫進度指示器,向用戶顯示正在進行的操作的狀態。如果您可以隨時估計操作需要多長時間以及完成多少操作,請使用指標的“確定”形式(進度條)。如果無法估計操作的長度,請使用指標的“不確定”形式(活動指示器)。

使用平臺的ProgressBar類實現顯示進度指示器。

要在從Android 4.0開始的平臺上使用進度指示器,請調用setProgress()。對於以前的版本,您必須創建自己的自定義通知佈局,其中包括ProgressBar視圖。

以下部分介紹如何使用setProgress()顯示通知中的進度。

顯示固定持續時間進度指示器

要顯示確定的進度條,請通過調用setProgress(max,progress,false)將欄添加到通知中,然後發出通知。隨着操作的進行,增加進度並更新通知。在操作結束時,進度應該等於最大值。調用setProgress()的常用方法是將max設置爲100,然後將progress作爲操作的“完成百分比”值遞增。

您可以在操作完成時退出進度條,也可以將其刪除。在任何一種情況下,請記住更新通知文本以顯示操作已完成。要刪除進度條,請調用setProgress(0,0,false)。例如:

...
mNotifyManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentTitle("Picture Download")
    .setContentText("Download in progress")
    .setSmallIcon(R.drawable.ic_notification);
// Start a lengthy operation in a background thread
new Thread(
    new Runnable() {
        @Override
        public void run() {
            int incr;
            // Do the "lengthy" operation 20 times
            for (incr = 0; incr <= 100; incr+=5) {
                    // Sets the progress indicator to a max value, the
                    // current completion percentage, and "determinate"
                    // state
                    mBuilder.setProgress(100, incr, false);
                    // Displays the progress bar for the first time.
                    mNotifyManager.notify(0, mBuilder.build());
                        // Sleeps the thread, simulating an operation
                        // that takes time
                        try {
                            // Sleep for 5 seconds
                            Thread.sleep(5*1000);
                        } catch (InterruptedException e) {
                            Log.d(TAG, "sleep failure");
                        }
            }
            // When the loop is finished, updates the notification
            mBuilder.setContentText("Download complete")
            // Removes the progress bar
                    .setProgress(0,0,false);
            mNotifyManager.notify(ID, mBuilder.build());
        }
    }
// Starts the thread by calling the run() method in its Runnable
).start();

顯示持續活動指標

要顯示不確定的活動指示符,請使用setProgress(0,0,true)將其添加到通知中(忽略前兩個參數),然後發出通知。結果是一個與進度條具有相同樣式的指示器,但其動畫正在進行中。

在操作開始時發出通知。動畫將一直運行,直到您修改通知爲止。操作完成後,調用setProgress(0,0,false),然後更新通知以刪除活動指示符。總是這樣做;否則,即使操作完成,動畫也會運行。還要記住更改通知文本以指示操作已完成。

要了解活動指標的工作原理,請參閱前面的代碼段。找到以下行:

// Sets the progress indicator to a max value, the current completion
// percentage, and "determinate" state
mBuilder.setProgress(100, incr, false);
// Issues the notification
mNotifyManager.notify(0, mBuilder.build());

用以下行替換您找到的行:

 // Sets an activity indicator for an operation of indeterminate length
mBuilder.setProgress(0, 0, true);
// Issues the notification
mNotifyManager.notify(0, mBuilder.build());

通知元數據


可以根據您使用以下NotificationCompat.Builder方法分配的元數據對通知進行排序:

  • setCategory()告訴系統當設備處於優先級模式時如何處理應用程序通知(例如,如果您的通知代表來電,即時消息或警報)。
  • 如果通知也有聲音或振動,setPriority()會將優先級字段設置爲PRIORITY_MAX或PRIORITY_HIGH的通知顯示在小浮動窗口中。
  • addPerson()允許您向通知添加人員列表。您的應用可以使用此功能向系統發出信號,告知系統應將來自指定人員的通知組合在一起,或者將來自這些人的通知排名爲更重要。

擡頭通知


使用Android 5.0(API級別21),當設備處於活動狀態時(即設備已解鎖且其屏幕處於打開狀態),通知可以顯示在小型浮動窗口(也稱爲擡頭通知)中。這些通知看起來類似於通知的緊湊形式,除了擡頭通知還顯示操作按鈕。用戶可以在不離開當前應用的情況下處理或解除提前通知。

可能觸發擡頭通知的條件示例包括:

  • 用戶的活動處於全屏模式(應用程序使用fullScreenIntent),或
  • 通知具有高優先級並使用鈴聲或振動

鎖定屏幕通知


隨着Android 5.0(API級別21)的發佈,通知現在可能會出現在鎖定屏幕上。您的應用可以使用此功能來提供媒體播放控件和其他常見操作。用戶可以通過“設置”選擇是否在鎖定屏幕上顯示通知,還可以指定是否在鎖定屏幕上顯示應用程序的通知。

設置可見性

您的應用可以控制安全鎖定屏幕上顯示的通知中可見的詳細程度。您調用setVisibility()並指定以下值之一:

  • VISIBILITY_PUBLIC顯示通知的完整內容。
  • VISIBILITY_SECRET在鎖定屏幕上不顯示此通知的任何部分。
  • VISIBILITY_PRIVATE顯示基本信息,例如通知的圖標和內容標題,但隱藏通知的完整內容。

設置VISIBILITY_PRIVATE後,您還可以提供隱藏某些詳細信息的備用通知內容版本。例如,SMS應用程序可能會顯示一條通知,顯示您有3條新短信,但會隱藏郵件內容和發件人。要提供此備用通知,請首先使用NotificationCompat.Builder創建替換通知。創建私有通知對象時,通過setPublicVersion()方法將替換通知附加到該對象。

控制鎖定屏幕上的媒體播放

在Android 5.0(API級別21)中,鎖定屏幕不再顯示基於RemoteControlClient的媒體控件,該控件現已棄用。而是將NotificationCompat.MediaStyle模板與addAction()方法一起使用,該方法將操作轉換爲可單擊的圖標。

要在Android 5.0的鎖定屏幕上顯示媒體播放控件,請將可見性設置爲VISIBILITY_PUBLIC,如上所述。然後添加操作並設置NotificationCompat.MediaStyle模板,如以下示例代碼中所述:

Notification notification = new NotificationCompat.Builder(context)
    // Show controls on lock screen even when user hides sensitive content.
    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
    .setSmallIcon(R.drawable.ic_stat_player)
    // Add media control buttons that invoke intents in your media service
    .addAction(R.drawable.ic_prev, "Previous", prevPendingIntent) // #0
    .addAction(R.drawable.ic_pause, "Pause", pausePendingIntent)  // #1
    .addAction(R.drawable.ic_next, "Next", nextPendingIntent)     // #2
    // Apply the media style template
    .setStyle(new NotificationCompat.MediaStyle()
        .setShowActionsInCompactView(1 /* #1: pause button */)
        .setMediaSession(mMediaSession.getSessionToken()))
    .setContentTitle("Wonderful music")
    .setContentText("My Awesome Band")
    .setLargeIcon(albumArtBitmap)
    .build();

注意:RemoteControlClient的棄用對控制媒體有進一步的影響。有關用於管理媒體會話和控制播放的新API的詳細信息,請參閱媒體播放控制。

自定義通知佈局


通知框架允許您定義自定義通知佈局,該佈局定義通知在RemoteViews對象中的外觀。自定義佈局通知與普通通知類似,但它們基於XML佈局文件中定義的RemoteView。

自定義通知佈局的可用高度取決於通知視圖。普通視圖佈局限制爲64 dp,擴展視圖佈局限制爲256 dp。

要定義自定義通知佈局,請首先實例化一個擴展XML佈局文件的RemoteViews對象。然後,調用setContent()而不是調用setContentTitle()等方法。要在自定義通知中設置內容詳細信息,請使用RemoteViews中的方法設置視圖子項的值:

1.在單獨的文件中爲通知創建XML佈局。您可以使用任何所需的文件名,但必須使用擴展名.xml

2.在您的應用程序中,使用RemoteViews方法定義通知的圖標和文本。通過調用setContent()將此RemoteViews對象放入NotificationCompat.Builder中。避免在RemoteViews對象上設置背景Drawable,因爲文本顏色可能變得不可讀。

RemoteViews類還包括可用於輕鬆地將Chronometer或ProgressBar添加到通知佈局的方法。有關爲通知創建自定義佈局的更多信息,請參閱RemoteViews參考文檔。

警告:使用自定義通知佈局時,請特別注意確保自定義佈局使用不同的設備方向和分辨率。雖然此建議適用於所有View佈局,但對於通知尤爲重要,因爲通知抽屜中的空間非常有限。不要使自定義佈局過於複雜,並確保以各種配置進行測試。

使用樣式資源自定義通知文本

始終將樣式資源用於自定義通知的文本。通知的背景顏色可能因設備和版本而異,使用樣式資源可幫助您解決此問題。從Android 2.3開始,系統爲標準通知佈局文本定義了一種樣式。如果您在面向Android 2.3或更高版本的應用程序中使用相同的樣式,則可以確保您的文本在顯示背景下可見。

自定義視圖

從Android 7.0(API級別24)開始,您可以自定義通知視圖,並仍然可以獲取通知標題,操作和可擴展布局等系統裝飾。

要啓用此功能,Android會提供以下API來設置自定義視圖的樣式:

DecoratedCustomViewStyle()

除媒體通知之外的樣式通知。

DecoratedMediaCustomViewStyle()

樣式媒體通知。

要使用此API,請調用setStyle()方法,並向其傳遞所需的自定義視圖樣式。

此代碼段顯示如何使用DecoratedCustomViewStyle()方法構造自定義通知對象。

Notification notification = new Notification.Builder()
           .setSmallIcon(R.drawable.ic_stat_player)
           .setLargeIcon(albumArtBitmap))
           .setCustomContentView(contentView);
           .setStyle(new Notification.DecoratedCustomViewStyle())
           .build();

消息風格

從Android 7.0(API級別24)開始,Android提供了一個用於自定義通知樣式的API。使用MessagingStyle類,您可以更改通知上顯示的多個標籤,包括會話標題,其他消息和通知的內容視圖。

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

  Notification notification = new Notification.Builder()
             .setStyle(new Notification.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();

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章