天天看點

PendingIntent

Intent和PendingIntent的關系,初學的時候很迷惑,用PendingIntent的時候,還會出現奇怪的問題,比如無法傳遞資料,無法更新資料,是以我集衆家之長,加上我個人的一些實踐,總結如下,希望能給你一些幫助。

首先看官方解釋:An Intent is something that is used right now; a PendingIntent is something that may create an Intent in the future. You will use a PendingIntent with Notifications, AlarmManager, etc.

Intent大家都很熟悉了,就是一個意圖,這個意圖表明要啟動哪個Activity,Service,PendingIntent可以看作是對Intent的進一步封裝,它是對Intent的描述,我們可以把這個描述交給别的程式,别的程式根據這個描述在後面的時間做你安排做的事情,下面是一個發送SMS短信的例子:

String msg ="你好";    

String number = "135****6784";    

SmsManager sms = SmsManager.getDefault();    

PendingIntent pi = PendingIntent.getBroadcast(SmsActivity.this,0,new Intent(XXX),0);    

sms.sendTextMessage(number, null, msg, pi, null);    

Toast.makeText(SmsActivity.this,"發送成功",Toast.LENGHT_LONG).show();    

方法SmsManager.sendTextMessage(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent):

PendingIntent sentIntent:當短信發出時,成功的話sendIntent會把其内部的描述的intent廣播出去,當然失敗之後會産生錯誤代碼,并通過 android.app.PendingIntent.OnFinished進行回調("Callback");

PendingIntent deliveryIntent:是當消息已經傳遞給收信人後所進行的Intent廣播;

如果你的BroadcastReveiver注冊接收相應的消息,你就會收到相應的Intent,這時候就可以根據Intent的Action,執行相應的動作,這就是上面說的in the future的含義;

有三個靜态方法可以獲得PendingIntent執行個體:

public static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)  

public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags)  

public static PendingIntent getService(Context context, int requestCode, Intent intent, int flags) 

flags參數有三個,我覺得英文更好了解:

FLAG_ONE_SHOT:this PendingIntent can only be used once. If set, after send() is called on it, it will be automatically canceled for you and any future attempt to send through it will fail.

FLAG_UPDATE_CURRENT: if the described PendingIntent already exists, then keep it but its replace its extra data with what is in this new Intent. This can be used if you are creating intents where only the extras change, and don't care that any entities that received your previous PendingIntent will be able to launch it with your new extras even if they are not explicitly given to it.

這個簡單解釋一下,就是當存在時,先把原來的取消,然後建立一個新的,在AlarmManager服務時,修改一個鬧鈴,用的比較笨的的方法,先取消,然後重新注冊,其實加上這個參數就行了。

要注意的是,這個隻更新extra data,不會修改其他内容,不能new一個Intent,還有就是如果你的Intent中需要傳遞Id或者其他資料,一定要用這個flags或者FLAG_CANCEL_CURRENT,曾經一直接收不到Id,查了半天原來是這個原因 :-(

LAG_NO_CREATE:if the described PendingIntent does not already exist, then simply return null instead of creating it.

LAG_CANCEL_CURRENT:if the described PendingIntent already exists, the current one is canceled before generating a new one.You can use this to retrieve a new PendingIntent when you are only changing the extra data in the Intent; by canceling the previous pending intent, this ensures that only entities given the new data will be able to launch it. If this assurance is not an issue, consider FLAG_UPDATE_CURRENT.

上面4個flag中最經常使用的是FLAG_UPDATE_CURRENT,因為描述的Intent有更新的時候需要用到這個flag去更新你的描述(确切的說是更新extra data),否則元件在下次事件發生或時間到達的時候extras永遠是第一次Intent的extras,使用FLAG_CANCEL_CURRENT也能做到更新extras,隻不過是先把前面的extras清除,另外FLAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT的差別在于能否新new一個Intent,FLAG_CANCEL_CURRENT能夠新new一個Intent,而FLAG_UPDATE_CURRENT則不能,隻能使用第一次的Intent。

 還有一個問題就是怎麼區分PendingIntent,主要取消的時候要用到,requestCode可以區分,但系統還是根據Intent的Action去區分的,如果Intent設定了Class,classData,取消的時候Intent一定要設定要相同的,不然取消不掉就可能出現取消後,Alarm還會響的問題,PendingIntent用的地方蠻多的,像 Notifications, AlarmManager等都會用到。。。

本文轉自 breezy_yuan 51CTO部落格,原文連結:http://blog.51cto.com/lbrant/424154,如需轉載請自行聯系原作者

繼續閱讀