最近在研究Android,遇到了一些Notification(通知)的問題: html
一、Notification如何傳遞參數 this
二、Notification如何區別化 spa
三、從Intent(意圖)尋找Activity(活動)提及,Android的Activity棧。 code
=============================================================== htm
先從發送通知開始。 對象
首先,在發送一個Notification前,咱們須要準備好一個NotificationManager blog
得到途徑: 事件
NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); ci
this爲Application或者Activity。 get
而後,定義好咱們的Notification:
一、定義一個Notification具有的三個基本參數icon,title,以及when
int icon=R.drawable.teller_call_1;
long when = System.currentTimeMillis();
Notification notification =new Notification(icon,null, when);
|
這個定義比較隨意。
二、爲notification添加打開關閉方式:
//點擊notification以後,該notification自動消失 notification.flags = Notification.FLAG_AUTO_CANCEL; //notification被notify的時候,觸發默認聲音和默認震動 notification.defaults=notification.DEFAULT_SOUND|notification.DEFAULT_VIBRATE;
三、爲notification添加一個意圖(Intent):
//該意圖用來打開NotificationList這個新的Activity Intent openintent= new Intent(this, NotificationList.class); //包裝該Intent,只有包裝後的Intent才能被Notification所用,這是由於Notification須要指定一些額外的參數 PendingIntent contentIntent = PendingIntent.getActivity(tradeRoom .getApplicationContext(), 0, openintent, 0); notification.setLatestEventInfo(tradeRoom.getApplicationContext(), title, info, contentIntent);
四、發送通知
//notifacation_id由本身指定,爲每個Notification對應的惟一標誌 mNotificationManager.notify(notifacation_id, notification);
======================================================
看到這裏,咱們明白了,咱們能夠爲Notification指定它的圖標,標題,時間,提醒方式,點擊以後的動做。
延展想一下,咱們還能作什麼呢?
一、因爲每一個Notification的ID是惟一的,因此咱們能夠刪除某些通知:
mNotificationManager.cancel(notifacation_id);
二、同理,經過重複發送相同ID的Notification,咱們還能夠更新某些通知:
mNotificationManager.notify(notifaction_id,newNotification);
三、因爲Notification的包裝內容爲Intent,咱們就能夠方便地爲通知被點擊的觸發的事件傳值:
Intent openintent= new Intent(this, NotificationList.class); openintent.putExtra("isRead", true); openintent.putExtra("name", "CaiYu");
等等,真的能夠傳值麼?
答案是能夠,可是,這樣傳值就完蛋了。
如今回到下面的位置來:
PendingIntent contentIntent = PendingIntent.getActivity(tradeRoom .getApplicationContext(), 0, openintent, 0);
注意最後一個「0」,0表示什麼?表示什麼都不作,而後下次你傳進來的Intent,若是被發現是同一個Intent,則全部通知都保持爲同一個Intent。好吧,事實上,Intent並非同一個,只是Extra被保留了。
嗯,你應該會指望每一個Notification都能幹點不同的事情,按上面的方式這樣來,每一個具有相同Intent的Notification相互之間,實際上是毫無區別的。
好,咱們來看下除了0之外Android還有什麼設置:
一、PendingIntent.FLAG_UPDATE_CURRENT
Extra會被更新爲最後一個傳入的Intent的Extra
二、PendingIntent.FLAG_ONE_SHOT
send()只能被執行一次,便是說,假如該通知點擊後不消失,那麼再次點擊不會發生任何事。
三、PendingIntent.FLAG_NO_CREATE
這個最好別用,不建立。
四、PendingIntent.FLAG_CANCEL_CURRENT
這個,會更新Extra,但仍是全部的Intent都保持同一個Extra。
嗯,明顯都不是你想要的。
其實答案根本不在PendingIntent包裝上。
PendingIntent所作的所有事情都只是對一樣的Intent進行處理,關鍵詞,在於「一樣的」
既然每次你打開的都一個Intent,那區分PendingIntent就沒有意義了
因此,在Intent定義的時候,你還須要區分Intent
推薦方式:
openintent.setData(Uri.parse("custom://"+System.currentTimeMillis()));
這樣就實現了Intent的區別化,之後每次傳入的Intent都會具有不一樣的Extra,固然,PendingIntent須要定義爲PendingIntent.FLAG_UPDATE_CURRENT
到這個地方,其實還剩下一個問題,很快你就會發現
每次點擊通知,都正確的彈出你要的Activity,可是以前的打開的Activity依舊存在
方法有二:
一、在Activity的onPause()方法體中增長:
finish();
這樣,在打開新的Activity的時候,舊的就進入了暫停態,啓動onPause(),而後執行finish(),活動結束
好吧,這是個蠢辦法,請不要使用
二、設置Intent:
openintent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
是的,這句就夠了,這裏我得說一下Activity的棧機制:
咱們先來看看Intent的結構new Intent(context(),Notification.class);
第一個參數爲產生該意圖(Intent)的活動,這個邏輯再清晰不過了,要作的事情得有個發出的主體
第二個參數爲該意圖的對象,便是這個意圖是什麼,咱們來看看。
呃!??這裏沒有對象……
是的,咱們只有了一個對象的類名,但遠遠不是某個具體的對象,這是反射麼?反射能經過一個類名來找到某個特定的類實例麼?
實現以下:
Android有一個棧機制,每一個產生的活動在過了產生期後,都會進入這個棧,新的活動壓着舊的活動,每一次尋找類名的時候,都默認提取的是棧頂的活動。這也是爲何Android能快捷的執行返回操做。
回到原點來,咱們爲Intent添加:
openintent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
以後,這個意圖一旦產生,就會自動清除棧頂的活動,便是說,上一個被打開的活動會被終結掉,因而就實現了沒有兩個相同的活動被同時打開。