Android的Notification研究

Android的Notification研究

最近在研究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);

以後,這個意圖一旦產生,就會自動清除棧頂的活動,便是說,上一個被打開的活動會被終結掉,因而就實現了沒有兩個相同的活動被同時打開。 

分類:  Android
相關文章
相關標籤/搜索