轉載自 http://www.cnblogs.com/travellife/css
html
Notification,是一種具備全局效果的通知,能夠在系統的通知欄中顯示。當 APP 向系統發出通知時,它將先以圖標的形式顯示在通知欄中。用戶能夠下拉通知欄查看通知的詳細信息。通知欄和抽屜式通知欄均是由系統控制,用戶能夠隨時查看。下面兩張圖均是來自 Google 官方文檔。java

圖 1 .通知欄中的通知android

圖 2 .抽屜式通知欄中的通知git
通知的目的是告知用戶 App 事件。在平時的使用中,通知主要有如下幾個做用:github
其中,前兩點能夠歸結爲與用戶交互,第三點是實時的任務提醒,但不能否認的是,第三點也會與用戶交互。微信
Notification 做爲 Android 重要的用戶界面組成部分,它有本身的設計指南。在 Android 5.0(Api level 21) 中引入的 Material Design 尤其重要。關於 Notification 的設計指南請參考 Notification Pattern併發
Notification 的概述就這麼多,接下去就開始講 Notification 的基本使用,中間會穿插 Notification 的基本 UI 、各個版本的區別、常見的通知效果以及本身在學習過程當中踩到的坑。less
Notification 的基本操做主要有建立、更新、取消這三種。一個 Notification 的必要屬性有三項,若是不設置則在運行時會拋出異常:ide
除了以上三項,其它均爲可選項。雖然如此,但仍是應該給 Notification 設置一個 Action ,這樣就能夠直接跳轉到 App 的某個 Activity 、啓動一個 Service 或者發送一個 Broadcast。不然,Notification 僅僅只能起到通知的效果,而不能與用戶交互。
當系統接收到通知時,能夠經過震動、響鈴、呼吸燈等多種方式進行提醒。
Notification 的建立主要涉及到 Notification.Builder 、 Notification 、 NotificationManager 。
獲取 NotificationManager 對象:
NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
前面講到,Notification 有三個必要屬性。下面,咱們就來建立一個簡單的 Notification 。主要有如下三步:
private void sendNotification() { //獲取NotificationManager實例 NotificationManager notifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); //實例化NotificationCompat.Builde並設置相關屬性 NotificationCompat.Builder builder = new NotificationCompat.Builder(this) //設置小圖標 .setSmallIcon(R.mipmap.icon_fab_repair) //設置通知標題 .setContentTitle("最簡單的Notification") //設置通知內容 .setContentText("只有小圖標、標題、內容") //設置通知時間,默認爲系統發出通知的時間,一般不用設置 //.setWhen(System.currentTimeMillis()); //經過builder.build()方法生成Notification對象,併發送通知,id=1 notifyManager.notify(1, builder.build()); }
以上代碼是對 Android 3.0 及以後的版本而言(包括使用 Support Library),對於 Android 3.0 以前的版本,主要使用 new Notification() 方法來建立 Notification 對象,本文不對此方式作任何講解,代碼以下:
NotificationManager mNotifyMgr =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE); PendingIntent contentIntent = PendingIntent.getActivity( this, 0, new Intent(this, ResultActivity.class), 0); Notification notification = new Notification(icon, tickerText, when); notification.setLatestEventInfo(this, title, content, contentIntent); mNotifyMgr.notify(NOTIFICATIONS_ID, notification);
補充:
Android Support v4:這個包是爲了照顧1.6及更高版本而設計的,這個包是使用最普遍的。 Android Support v7:這個包是爲了考慮照顧2.1及以上版本而設計的,但不包含更低,故若是不考慮1.6,咱們能夠採用再加上這個包,另外注意,v7是要依賴v4這個包的,即,兩個得同時被包含。 Android Support v13:這個包的設計是爲了android 3.2及更高版本的,通常咱們都不經常使用,平板開發中能用到。
Google 官方是這麼解釋 setSmallIcon()
這個方法的:
Set the small icon resource, which will be used to represent the notification in the status bar. The platform template for the expanded view will draw this icon in the left, unless a large icon has also been specified, in which case the small icon will be moved to the right-hand side.
在前一章節 建立 Notification 中發送的通知並不具有與用戶交互的能力,這是由於咱們並無給 Notification 設置 Action 。在這一節,咱們就來說講如何給 Notification 設置 Action 。這裏,咱們來實現一個點擊 Notification 跳轉到 MainActivity 的效果。代碼以下:
/** * 發送一個點擊跳轉到MainActivity的消息 */ private void sendSimplestNotificationWithAction() { //獲取PendingIntent Intent mainIntent = new Intent(this, MainActivity.class); PendingIntent mainPendingIntent = PendingIntent.getActivity(this, 0, mainIntent, PendingIntent.FLAG_UPDATE_CURRENT); //建立 Notification.Builder 對象 NotificationCompat.Builder builder = new NotificationCompat.Builder(this) .setSmallIcon(R.mipmap.ic_launcher) //點擊通知後自動清除 .setAutoCancel(true) .setContentTitle("我是帶Action的Notification") .setContentText("點我會打開MainActivity") .setContentIntent(mainPendingIntent); //發送通知 mNotifyManager.notify(3, builder.build()); }
相比發送最簡單的通知,發送具備 Action 的通知多了建立 Intent 、 PendingIntent 和 setContentIntent() 這幾步。
不難看出, PendingIntent 纔是重點,那麼, PendingIntent 是什麼呢?
若是您瞭解 PendingIntent ,請直接跳過本節。
PendingIntent 是一種特殊的 Intent ,字面意思能夠解釋爲延遲的 Intent ,用於在某個事件結束後執行特定的 Action 。從上面帶 Action 的通知也能驗證這一點,當用戶點擊通知時,纔會執行。
PendingIntent 是 Android 系統管理並持有的用於描述和獲取原始數據的對象的標誌(引用)。也就是說,即使建立該PendingIntent對象的進程被殺死了,這個PendingItent對象在其餘進程中仍是可用的。
平常使用中的短信、鬧鐘等都用到了 PendingIntent。
PendingIntent 主要能夠經過如下三種方式獲取:
//獲取一個用於啓動 Activity 的 PendingIntent 對象 public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags); //獲取一個用於啓動 Service 的 PendingIntent 對象 public static PendingIntent getService(Context context, int requestCode, Intent intent, int flags); //獲取一個用於向 BroadcastReceiver 廣播的 PendingIntent 對象 public static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)
PendingIntent 具備如下幾種 flag:
FLAG_CANCEL_CURRENT:若是當前系統中已經存在一個相同的 PendingIntent 對象,那麼就將先將已有的 PendingIntent 取消,而後從新生成一個 PendingIntent 對象。 FLAG_NO_CREATE:若是當前系統中不存在相同的 PendingIntent 對象,系統將不會建立該 PendingIntent 對象而是直接返回 null 。 FLAG_ONE_SHOT:該 PendingIntent 只做用一次。 FLAG_UPDATE_CURRENT:若是系統中已存在該 PendingIntent 對象,那麼系統將保留該 PendingIntent 對象,可是會使用新的 Intent 來更新以前 PendingIntent 中的 Intent 對象數據,例如更新 Intent 中的 Extras 。
更新通知很簡單,只須要再次發送相同 ID 的通知便可,若是以前的通知還未被取消,則會直接更新該通知相關的屬性;若是以前的通知已經被取消,則會從新建立一個新通知。
更新通知跟發送通知使用相同的方式。詳見上節:建立 Notification
取消通知有以下 5 種方式:
若是你是經過 NotificationManager.notify(String tag, int id, Notification notify) 方法建立的通知,那麼只能經過 NotificationManager.cancel(String tag, int id) 方法才能清除對應的通知,調用NotificationManager.cancel(int id) 無效。
關於 Notification 的基本操做代碼以下,佈局文件代碼這就不貼了。我是 Demo 傳送門:
/** * 爲了方便,大部分通知都沒設置對應的Action,即PendingIntent * 除了sendFlagAutoCancelNotification()方法 */ public class SimpleNotificationActivity extends Activity implements View.OnClickListener { //Notification.FLAG_FOREGROUND_SERVICE //表示正在運行的服務 public static final String NOTIFICATION_TAG = "littlejie"; public static final int DEFAULT_NOTIFICATION_ID = 1; private NotificationManager mNotificationManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_simple_notification); findViewById(R.id.btn_remove_all_notification).setOnClickListener(this); findViewById(R.id.btn_send_notification).setOnClickListener(this); findViewById(R.id.btn_remove_notification).setOnClickListener(this); findViewById(R.id.btn_send_notification_with_tag).setOnClickListener(this); findViewById(R.id.btn_remove_notification_with_tag).setOnClickListener(this); findViewById(R.id.btn_send_ten_notification).setOnClickListener(this); findViewById(R.id.btn_send_flag_no_clear_notification).setOnClickListener(this); findViewById(R.id.btn_send_flag_ongoing_event_notification).setOnClickListener(this); findViewById(R.id.btn_send_flag_auto_cancecl_notification).setOnClickListener(this); mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_remove_all_notification: //移除當前 Context 下全部 Notification,包括 FLAG_NO_CLEAR 和 FLAG_ONGOING_EVENT mNotificationManager.cancelAll(); break; case R.id.btn_send_notification: //發送一個 Notification,此處 ID = 1 sendNotification(); break; case R.id.btn_remove_notification: //移除 ID = 1 的 Notification,注意:該方法只針對當前 Context。 mNotificationManager.cancel(DEFAULT_NOTIFICATION_ID); break; case R.id.btn_send_notification_with_tag: //發送一個 ID = 1 而且 TAG = littlejie 的 Notification //注意:此處發送的通知與 sendNotification() 發送的通知並不衝突 //由於此處的 Notification 帶有 TAG sendNotificationWithTag(); break; case R.id.btn_remove_notification_with_tag: //移除一個 ID = 1 而且 TAG = littlejie 的 Notification //注意:此處移除的通知與 NotificationManager.cancel(int id) 移除通知並不衝突 //由於此處的 Notification 帶有 TAG mNotificationManager.cancel(NOTIFICATION_TAG, DEFAULT_NOTIFICATION_ID); break; case R.id.btn_send_ten_notification: //連續發十條 Notification sendTenNotifications(); break; case R.id.btn_send_flag_no_clear_notification: //發送 ID = 1, flag = FLAG_NO_CLEAR 的 Notification //下面兩個 Notification 的 ID 都爲 1,會發現 ID 相等的 Notification 會被最新的替換掉 sendFlagNoClearNotification(); break; case R.id.btn_send_flag_auto_cancecl_notification: sendFlagOngoingEventNotification(); break; case R.id.btn_send_flag_ongoing_event_notification: sendFlagAutoCancelNotification(); break; } } /** * 發送最簡單的通知,該通知的ID = 1 */ private