注:爲了給許多各類不一樣的平臺提供最好的notification支持,應該使用NotificationCompat以及它的子類,特別是NotificationCompat.Builder,因此如下通知均引用版本 4 支持庫中的 NotificationCompat.Builder 類。java
通知建立步驟:
android
經過NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)得到一個通知的Builder對象;併發
調用mBuilder的方法設置通知屬性,如setSmallIcon(int drawable)、satContentTitle(CharSquence title)等爲通知設置小圖標、內容標題;app
經過mBuilder.build()方法得到一個Notification對象;ide
得到一個通知管理器NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE),經過nm.notify(int id, Notification notification)方法發送通知,至此,通知便已經發送出去佈局
建立一個通知時,必須包含一下幾項內容:動畫
小圖標:由 setSmallIcon() 設置ui
標題:由 setContentTitle() 設置this
詳細文本:由 setContentText() 設置spa
建立通知時,雖然能夠選擇爲通知設置操做與否,可是通常來講,至少應該爲通知設定一個操做。最多見的通知操做即是由該通知跳轉至指定的Activity,在該Activity中,有用戶須要查看的消息或者是用戶須要進行的操做
//建立一個用於通知操做的Intent Intent intent = new Intent(); intent.setClass(mContext, IconifyActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); //建立一個NotificationCompat.Builder對象,經過該對象爲通知設置屬性,並構建一個具體地通知 NotificationCompat.Builder builder = new NotificationCompat.Builder(this); Notification simpleNotice = builder.setContentTitle("Simple notice").setContentText("Example for simple notice").setSmallIcon(R.drawable.ic_notice_1).setContentIntent(pendingIntent) .setAutoCancel(true).setDefaults(Notification.DEFAULT_ALL).setPriority(Notification.PRIORITY_HIGH) .build(); //得到一個通知管理器,經過該管理器發送通知 NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.notify(0, simpleNotice);
效果圖以下:
有時,設定一個Notification是爲了保持應用的導航性,用戶點擊通知時會進入含有具體操做的Activity。一般,Activity分爲兩類,常規的Activity和特定的Activity。
常規Activity是你的應用工做流中的一部分,而一個特定的Activity並不位於你的應用工做流中,通常位於一個新的任務棧中,只能經過notification來啓動。
上述示例就是經過notification導航進入一個常規Activity,不過一般還應該爲跳轉至常規Activity的通知設定一個返回棧,用於將該Activity導航回上一級Activity。下述步驟介紹如何發送一個跳轉至另外一任務棧的Activity的通知。
在manifest.xml文件中爲該Activity設置以下屬性android:taskAffinity="",該屬性用於標誌該activity須要進入的任務棧,結合代碼中設置的FLAG_ACTIVITY_NEW_TASK標識, 確保這個Activity不會進入application的默認任務:
<!-- 設置NewTaskActivity處於一個新的task中,從而不會進入應用程序默認的task --> <!-- taskAffinity是一個task標誌,標誌該activity應該進入的task --> <!-- excludeFromRecents屬性用於將新任務從最近列表中刪除,目的是爲了防止用戶不當心返回到它 --> <activity android:name="com.activity.NewTaskActivity" android:excludeFromRecents="true" android:launchMode="singleTask" android:taskAffinity="" /> <activity android:name="com.activity.IconifyActivity" /
在代碼中創建併發布notification
注意:須要調用Intent的setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_CLEAR_TASK)來確保Activity在一個新的空task中啓動
Intent intent = new Intent(); intent.setClass(this, NewTaskActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); Notification simpleNotice = builder.setContentTitle("New task notice").setContentText("Example for new task notice").setSmallIcon(R.drawable.ic_notice_2).setContentIntent(pendingIntent).build(); NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); nm.notify(0, simpleNotice);
效果以下(圖一是通知視圖,圖二是點擊通知後,長按Home鍵能夠看到的目前的任務列表)由圖二能夠看出,由該通知跳轉至的Activity位於一個新的任務棧中:
更新通知:更新通知是指發佈一條通知後,對剛發佈的這條通知進行修改;當使用notify(int id, Notification notification)方法發佈一條通知時,參數id表示的是當前發佈的通知的惟一id,因此當須要對該同志進行更新時,只須要再發布一條同一id號的新通知便可。如:
//發佈id=0的通知,具體通知內容爲notification1 nm.notify(0, notification1); //更新id=0的通知,具體通知內容爲notification2 nm.notify(0, notification2);
將同一類通知進行統一管理:當應用中須要發送同一類型的通知時,可將這些通知合併爲一條摘要通知,而不是每次都新建一條通知。具體的應用場景有如短信、即時消息等,如:
具體的代碼以下:
/** * 發送一條摘要通知,當同類型通知超出一條時,以摘要通知的形式展現 * @param count:已發出的該類通知數目 */ public void sendSummaryNotice(int count) { Intent summaryIntent = new Intent(mContext, IconifyActivity.class); PendingIntent summaryPI = PendingIntent.getActivity(mContext, 0, summaryIntent, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder summaryBuilder = new NotificationCompat.Builder(mContext); summaryBuilder.setContentIntent(summaryPI); if (count > 1) { summaryBuilder.setTicker("New summary msg").setSmallIcon(R.drawable.ic_summary_notice_1) .setContentTitle("Summary message").setContentText("You have received " + count + " message!") .setNumber(count); } else { summaryBuilder.setTicker("New message").setSmallIcon(R.drawable.ic_summary_notice_1) .setContentTitle("Msg " + count).setContentText("This is message " + count); } nm.notify(0, summaryBuilder.build()); }
效果圖以下(圖1是當該類通知只有一條時的樣子,圖2是當通知超出一條時的樣子,右下角的數字表示的是已發送的同類型通知數目,還能夠進一步設置當通知超出一條時,能夠點擊該通知展開顯示通知詳情):
通常來講,通知都是以上面所展現的普通視圖樣式呈現,但Android系統中還提供一種Big View樣式的通知。Big view樣式的通知只有當Notification在Notification抽屜的最上方或者用戶點擊Notification時纔會展示。同時,該樣式是在Android4.1才被引進的,因此它不支持老版本設備,在實現big view 樣式的通知時,要確保在Big view樣式中能完成的功能,經過普通視圖樣式的通知也可以完成(能夠在普通視圖跳轉至的Activity中提供此類功能)。
下圖是我實現的一個Big view樣式的通知:
代碼以下:
/** * 發送一個大視圖樣式的通知 */ public void sendaBigViewNotice() { //點擊通知的操做Intent Intent intent = new Intent(mContext, MainActivity.class); PendingIntent pi = PendingIntent.getActivity(mContext, 6, intent, PendingIntent.FLAG_UPDATE_CURRENT); //構造一個NotificationCompat.Builder,爲通知設置屬性值 NotificationCompat.Builder bigViewbuilder = new NotificationCompat.Builder(mContext) .setContentTitle("Big view notice") .setContentText("This is a big view notice") .setSmallIcon(R.drawable.ic_notice_6) .setContentIntent(pi) .setAutoCancel(true) .setDefaults(Notification.DEFAULT_ALL); //定義大視圖通知中自定義的兩個按鈕的操做 PendingIntent cameraPi = PendingIntent.getActivity(mContext, 101, new Intent(mContext, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT); PendingIntent refreshPi = PendingIntent.getActivity(mContext, 102, new Intent(mContext, IconifyActivity.class), PendingIntent.FLAG_UPDATE_CURRENT); //經過setStyle(Style style)方法設置通知的樣式爲BigTextStyle //經過addAction(int icon, CharSequence title, PendingIntent intent)方法爲通知添加動做 //參數一:動做圖標資源;參數二:動做名稱; 參數三:動做所對應的操做的PendingIntent bigViewbuilder .setStyle(new NotificationCompat.BigTextStyle().bigText("Big text").setSummaryText("This is a summary")) .addAction(R.drawable.ic_camera, "Camera", cameraPi) .addAction(R.drawable.ic_camera_alt, "Refresh", refreshPi); //發送通知 NotificationManager nm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); nm.notify(100, bigViewbuilder.build()); }
Notification中能夠包含一個動畫進度指示器,用於指示用戶正在進行的操做的進度。該進度指示器有兩種類型:determinate(肯定的) 和 indeterminate(不肯定的)。通常來講,若一個操做的具體完成時間已知,且當前已完成的部分所花的時間已知時,使用肯定性進度指示器;不然使用不肯定性進度指示器。
通知的進度指示器是用ProgressBar平臺實現類來顯示,用 setProgress(int max, int progress, boolean indeterminate)方法來設置的。該方法有三個參數:
max:進度條的最大值;
progress:當前已完成的進度值,通常來講,當操做完成時,progress應等於max,一般將max值設爲100,而後將progress值設爲當前完成值佔max的百分比;
indeterminate:一個boolean類型值,表示當前的進度條是爲indeterminate(true)仍是determinate(false);
注意:操做完成時,能夠選擇繼續顯示或移除進度條,可是必須的提供相應的文字說明,提示用戶操做已完成,移除進度條,只需使用setProgress(0, 0, false))方法便可
/** * 發送一個含有進度條的通知 * @param indeterminate:是否爲不肯定性進度條,true:不肯定性 false:肯定性 */ public void sendProgressNotice(final boolean indeterminate) { //點擊通知的操做 Intent intent = new Intent(mContext, IconifyActivity.class); final PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 10, intent, PendingIntent.FLAG_UPDATE_CURRENT); final NotificationCompat.Builder progressBuilder = new NotificationCompat.Builder(mContext) .setSmallIcon(R.drawable.ic_notice_6).setContentTitle("Progress notice") .setContentText("This is a progress notice").setTicker("Here is a new msg"); //新建一個線程,用於控制操做進度 new Thread(new Runnable() { @Override public void run() { //不肯定性進度指示器 if (indeterminate) { for (int inch = 0; inch <= 100; inch += 5) { progressBuilder.setProgress(0, 0, true); nm.notify(103, progressBuilder.build()); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } progressBuilder.setProgress(0, 0, false).setContentText("Finished the progress") .setContentIntent(pendingIntent); nm.notify(103, progressBuilder.build()); } else { //肯定性進度指示器 for (int inch = 0; inch < 100; inch += 5) { progressBuilder.setProgress(100, inch, false); nm.notify(104, progressBuilder.build()); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } //操做完成時,取消進度指示器,並設置提示文本 progressBuilder.setProgress(0, 0, false).setContentText("Finished the progress") .setContentIntent(pendingIntent); nm.notify(104, progressBuilder.build()); } } }).start(); }
效果圖以下(圖一:不肯定性進度條; 圖二:肯定性進度條; 圖三:操做完成後的狀態):
自定義佈局通知的使用步驟:
建立一個通知佈局文件(xml)
經過實例化一個RemoteViews對象加載該佈局文件
經過setContent(RemoteViews views)方法設置通知內容視圖爲一個該RemoteViews視圖
發佈該通知
public void sendCustomViewNotice() { //經過一個RemoteViews來加載通知佈局文件 RemoteViews remoteView = new RemoteViews(mContext.getPackageName(), R.layout.custom_notification); NotificationCompat.Builder customBuilder = new NotificationCompat.Builder(mContext); customBuilder.setSmallIcon(R.drawable.ic_notice_6); //經過setContent(RemoteViews views)方法設置通知內容視圖爲一個RemoteViews視圖 customBuilder.setContent(remoteView); Intent intent = new Intent(); intent.setClass(mContext, IconifyActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); customBuilder.setContentIntent(pendingIntent); nm.notify(0, customBuilder.build()); }
效果圖以下: