Android的Notification研究


最近在研究Android,遇到了一些Notification(通知)的問題:

1、Notification如何傳遞參數

2、Notification如何區別化

3、從Intent(意圖)尋找Activity(活動)說起,Android的Activity棧。

===============================================================

先從發送通知開始。

首先,在發送一個Notification前,我們需要准備好一個NotificationManager

獲得途徑:

NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);

this為Application或者Activity。

然后,定義好我們的Notification:

1、定義一個Notification具備的三個基本參數icon,title,以及when

int icon=R.drawable.teller_call_1;

long when = System.currentTimeMillis();

Notification notification = new Notification(icon, null, when);

  

這個定義比較隨意。

2、為notification添加打開關閉方式:

//點擊notification之后,該notification自動消失

notification.flags = Notification.FLAG_AUTO_CANCEL;

//notification被notify的時候,觸發默認聲音和默認震動

notification.defaults=notification.DEFAULT_SOUND|notification.DEFAULT_VIBRATE;



3、為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);



4、發送通知

//notifacation_id由自己指定,為每一個Notification對應的唯一標志

mNotificationManager.notify(notifacation_id, notification);



 

======================================================

看到這里,我們明白了,我們可以為Notification指定它的圖標,標題,時間,提醒方式,點擊之后的動作。

延展想一下,我們還能做什么呢?

1、由於每個Notification的ID是唯一的,所以我們可以刪除某些通知:

mNotificationManager.cancel(notifacation_id);



2、同理,通過重復發送相同ID的Notification,我們還可以更新某些通知:

mNotificationManager.notify(notifaction_id,newNotification);



3、由於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還有什么設置:

1、PendingIntent.FLAG_UPDATE_CURRENT

Extra會被更新為最后一個傳入的Intent的Extra

2、PendingIntent.FLAG_ONE_SHOT

send()只能被執行一次,即是說,假如該通知點擊后不消失,那么再次點擊不會發生任何事。

3、PendingIntent.FLAG_NO_CREATE

這個最好別用,不創建。

4、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依舊存在

方法有二:

1、在Activity的onPause()方法體中增加:

finish();

這樣,在打開新的Activity的時候,舊的就進入了暫停態,啟動onPause(),然后執行finish(),活動結束

好吧,這是個蠢辦法,請不要使用

2、設置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);

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM