Android Notification 詳解

ezy發表於2016-12-28

Link: www.jianshu.com/p/d2051a785…
Demo: github.com/czy1121/Not…

1. 簡單用法

建立通知

建立通知至少包含 小圖示、標題、內容 才能顯示

NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!");複製程式碼

傳送通知

NotificationManager manager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(notifyId, builder.build());複製程式碼

取消通知

NotificationManager manager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);

// 取消notifyId關聯的通知
manager.cancel(notifyId);

// 取消所有通知
manager.cancelAll();複製程式碼

2. 基本資訊

標題/內容/小圖示

必要資訊

// 標題
builder.setContentTitle("這是通知標題");
// 內容
builder.setContentText("這是通知內容");
// 小圖示
builder.setSmallIcon(R.mipmap.ic_small_icon);複製程式碼

大圖示

大圖示,未設定時使用小圖示代替

// 大圖示 
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_large_icon);
builder.setLargeIcon(bitmap);複製程式碼

次要內容

setContentInfo 在 api 24 被廢棄,不再顯示,用 setSubText 代替
setNumber 在 api 24 被廢棄,不再顯示

// 次要內容
builder.setSubText("這是通知的次要內容");
// 附加文字
builder.setContentInfo("INFO");
// 附加數字,等價於 setContentInfo, 為了顯示效果用一個不同的字型尺寸顯示數字
builder.setNumber(123);複製程式碼

時間

setShowWhen 在 api 17 被新增
setChronometerCountDown 在 api 24 新增

// 設定時間
builder.setWhen(System.currentTimeMillis())
// 設定是否顯示時間
builder.setShowWhen(false);
// 設定是否顯示時鐘表示時間(count up)
builder.setUsesChronometer(false););
// 設定時鐘是否為倒數計時(count down)
builder.setChronometerCountDown(false);複製程式碼

進度條

當使用了 setSubText() 後,進度條將不顯示
api 24 之後,setSubText() 不再影響進度條

int max = 100; // 進度最大值
int progress = 50;  // 當前進度
int indeterminate = false; // 是否是不明確的進度條
builder.setProgress(max, progress, indeterminate);複製程式碼

狀態列摘要(ticker)

在 api 21 後不再顯示,僅用於輔助服務。

builder.setTicker("this is ticker");複製程式碼

3. 標誌符(Flags)

Flag 描述
Notification.FLAG_SHOW_LIGHTS 是否使用呼吸燈提醒
Notification.FLAG_INSISTENT 持續提醒(聲音/振動)直到使用者響應(點選/取消)
Notification.FLAG_ONLY_ALERT_ONCE 提醒(鈴聲/震動/滾動通知摘要)只執行一次
Notification.FLAG_ONGOING_EVENT 正在進行中通知
Notification.FLAG_AUTO_CANCEL 使用者點選通知後自動取消
Notification.FLAG_NO_CLEAR 使用者無法取消
Notification.FLAG_FOREGROUND_SERVICE 表示正在執行的服務

設定是否使用呼吸燈提醒(FLAG_SHOW_LIGHTS)

通過 builder.setLightsbuilder.setDefaults 設定使用呼吸燈時會自動新增 FLAG_SHOW_LIGHTS

設定提醒只執行一次(FLAG_ONLY_ALERT_ONCE)

設定提醒只執行一次

builder.setOnlyAlertOnce(true);複製程式碼

設定自動取消(FLAG_AUTO_CANCEL)

需要同時設定了 setContentIntent() 才有效

builder.setAutoCancel(true);
builder.setContentIntent(pendingIntent);複製程式碼

設定通知為進行中(FLAG_ONGOING_EVENT)

通常表示一個使用者積極參與的後臺任務,比如電話,下載,播放音樂等

使用者不能取消,效果類似FLAG_NO_CLEAR
使用者點選通知且設定了自動取消時會被刪除

builder.setOngoing(true);複製程式碼

設定 FLAG_INSISTENT/FLAG_NO_CLEAR

NotificationCompat.Builder 未提供設定方法,只能通過 Notification

Notification n = builder.build();
// 持續提醒直到使用者響應
n.flags |= Notification.FLAG_INSISTENT;
// 使用者無法取消
n.flags |= Notification.FLAG_NO_CLEAR;
manager.notify(notifyId, n);複製程式碼

4. 優先順序

優先順序 描述
Notification.PRIORITY_MAX 重要而緊急的通知,通知使用者這個事件是時間上緊迫的或者需要立即處理的。
Notification.PRIORITY_HIGH 高優先順序用於重要的通訊內容,例如短訊息或者聊天,這些都是對使用者來說比較有興趣的
Notification.PRIORITY_DEFAULT 預設優先順序用於沒有特殊優先順序分類的通知
Notification.PRIORITY_LOW 低優先順序可以通知使用者但又不是很緊急的事件。只顯示狀態列圖示
Notification.PRIORITY_MIN 用於後臺訊息 (例如天氣或者位置資訊)。只有使用者下拉通知抽屜才能看到內容

設定優先順序

builder.setPriority(Notification.PRIORITY_HIGH);複製程式碼

5. 提醒通知到達

提供了 鈴聲/振動/呼吸燈 三種提醒方式,可以使用一種或同時使用多種

使用預設提醒

FLAG 描述
Notification.DEFAULT_SOUND 新增預設聲音提醒
Notification.DEFAULT_VIBRATE 新增預設震動提醒
Notification.DEFAULT_LIGHTS 新增預設呼吸燈提醒
Notification.DEFAULT_ALL 同時新增以上三種預設提醒
// 新增預設聲音提醒
builder.setDefaults(Notification.DEFAULT_SOUND);

// 新增預設呼吸燈提醒,自動新增FLAG_SHOW_LIGHTS
builder.setDefaults(Notification.DEFAULT_LIGHTS);複製程式碼

新增自定義提醒

// 新增自定義聲音提醒
builder.setSound(Uri.parse("path/to/sound"));

// 新增自定義震動提醒
// 延遲200ms後震動300ms,再延遲400ms後震動500ms
long[] pattern = new long[]{200,300,400,500}; 
builder.setVibrate(pattern);

// 新增自定義呼吸燈提醒,自動新增FLAG_SHOW_LIGHTS
int argb = 0xffff0000;  // led燈光顏色
int onMs = 300;         // led亮燈持續時間
int offMs = 100;        // led熄燈持續時間
builder.setLights(argb, onMs, offMs);複製程式碼

6. 事件

點選內容事件

int flags = PendingIntent.FLAG_UPDATE_CURRENT;
Intent intent = new Intent(this, ResultActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, intent, flags);
builder.setContentIntent(pi);複製程式碼

取消通知事件

通知被使用者取消時傳送(清除所有,右滑刪除)
“自動取消(FLAG_AUTO_CANCEL)”不會產生該事件

Intent intent = new Intent(ACTION);
intent.putExtra("op", op);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, 0);
builder.setDeleteIntent(pi);複製程式碼

全屏通知事件

響應緊急事件(比如來電)

Intent intent = new Intent(ACTION);
intent.putExtra("op", op);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, 0);
builder.setFullScreenIntent(pi, true);複製程式碼

7. 浮動通知

Android 5.0(API 21)開始支援浮動通知

裝置處於活動狀態(裝置未鎖定且其螢幕已開啟)時,可顯示浮動通知

滿足下列條件之一可觸發浮動通知:

  • 使用者的 Activity 處於全屏模式中(應用使用 fullScreenIntent)
  • 通知具有較高的優先順序(PRIORITY_MAX 或 PRIORITY_HIGH)並使用鈴聲或振動

注:國內各種ROM可能由於各種原因導致浮動通知不能顯示

8. 鎖定螢幕通知

Android 5.0(API 21)開始,通知可顯示在鎖定螢幕上。
可使用此功能提供媒體播放控制元件以及其他常用操作。
使用者可以通過“設定”選擇是否將通知顯示在鎖定螢幕上。

設定可見性

  • VISIBILITY_PUBLIC 顯示通知的完整內容。
  • VISIBILITY_SECRET 不會在鎖定螢幕上顯示此通知的任何部分。
  • VISIBILITY_PRIVATE 顯示通知圖示和內容標題等基本資訊,但是隱藏通知的完整內容。

設定 VISIBILITY_PRIVATE 後,還可以通過 setPublicVersion() 提供其中隱藏了某些詳細資訊的替換版本通知內容。

9. 擴充套件布局

Android 4.1(API 16) 開始支援擴充套件布局,下拉抽屜中最頂部的一條通知的擴充套件布局自動展開
Android 7.0(API 24) 開始每條通知都可以單獨展開

操作按鈕

api 19 開始支援新增操作按鈕,每個展開的通知可包含最多3個操作按鈕

// 新增操作按鈕
builder.addAction(icon1, title1, pendingIntent1);
builder.addAction(icon2, title2, pendingIntent2);複製程式碼

樣式

使用Builder.setStyle()設定擴充套件布局樣式

多行文字通知

Notification notif = new Notification.Builder(mContext)
     .setContentTitle("New mail from " + sender.toString())
     .setContentText(subject)
     .setSmallIcon(R.drawable.new_mail)
     .setLargeIcon(aBitmap)
     .setStyle(new Notification.BigTextStyle().bigText(aVeryLongString))
     .build();複製程式碼

大圖通知

Notification notif = new Notification.Builder(mContext)
     .setContentTitle("New photo from " + sender.toString())
     .setContentText(subject)
     .setSmallIcon(R.drawable.new_post)
     .setLargeIcon(aBitmap)
     .setStyle(new Notification.BigPictureStyle().bigPicture(aBigBitmap))
     .build();複製程式碼

收件箱通知

最多顯示5行訊息

 Notification notif = new Notification.Builder(mContext)
     .setContentTitle("5 New mails from " + sender.toString())
     .setContentText(subject)
     .setSmallIcon(R.drawable.new_mail)
     .setLargeIcon(aBitmap)
     .setStyle(new Notification.InboxStyle()
         .addLine(str1)
         .addLine(str2)
         .setContentTitle("")
         .setSummaryText("+3 more"))
     .build();複製程式碼

10. 保留 Activity 返回棧

常規 Activity

預設情況下,從通知啟動一個Activity,按返回鍵會回到主螢幕。

但某些時候有按返回鍵仍然留在當前應用的需求,這就要用到TaskStackBuilder了。

1、在manifest中定義Activity的關係

<activity
    android:name=".ResultActivity"
    android:parentActivityName=".MainActivity">
</activity>複製程式碼

2、構建帶返回棧的PendingIntent併傳送通知

// 構建返回棧
TaskStackBuilder tsb = TaskStackBuilder.create(this);
tsb.addParentStack(ResultActivity.class); 
tsb.addNextIntent(new Intent(this, ResultActivity.class));

// 構建包含返回棧的 PendingIntent
PendingIntent pi = tsb.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

// 構建通知
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
...
builder.setContentIntent(pi);

// 傳送通知
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(notifyId, builder.build());複製程式碼

特殊Activity

預設情況下,從通知啟動的Activity會在近期任務列表裡出現。

如果不需要在近期任務裡顯示,則需要做以下操作:

1、在manifest中定義Activity

<activity
    android:name=".ResultActivity"
    android:launchMode="singleTask"
    android:taskAffinity=""
    android:excludeFromRecents="true">
</activity>複製程式碼

2、構建PendingIntent併傳送通知

// 建立 Intent
Intent intent = new Intent(this, ResultActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

// 建立 PendingIntent
PendingIntent pi = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

// 構建通知
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
...
builder.setContentIntent(pi);

// 傳送通知
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(notifyId, builder.build());複製程式碼

Demo

github.com/czy1121/Not…

Android Notification 詳解
notify

api 19 (android 4.4)

Android Notification 詳解
api19_big_text
Android Notification 詳解
api19_big_picture

api 21 (android 5.0)

Android Notification 詳解
api21_big_text
Android Notification 詳解
api19_big_picture

Android Notification 詳解
api21_progress_bar
Android Notification 詳解
api21_heads_up

api 24 (android 7.0)

Android Notification 詳解
api24_basic
Android Notification 詳解
api24_progress_bar

Android Notification 詳解
api24_heads_up

參考

developer.android.com/reference/a…
developer.android.com/reference/a…
developer.android.com/guide/topic…

全面瞭解Android Notification
www.jianshu.com/p/22e27a639…

相關文章