android: PendingIntent的使用

pendingIntent字面意義:等待的,未決定的Intent。

要獲得一個pendingIntent對象,使用方法類的靜態方法
  getActivity(Context, int, Intent, int), getBroadcast(Context, int, Intent, int), getService(Context, int, Intent, int)  分別對應着Intent的3個行爲,跳轉到一個activity組件、打開一個廣播組件和打開一個服務組件。
參數有4個,比較重要的事第三個和第一個,其次是第四個和第二個。能夠看到,要獲得這個對象,必須傳入一個Intent做爲參數,必須有context做爲參數。
pendingIntent是一種特殊的Intent。主要的區別在於Intent的執行馬上的,而pendingIntent的執行不是馬上的。pendingIntent執行的操做實質上是參數傳進來的Intent的操做,可是使用pendingIntent的目的在於它所包含的Intent的操做的執行是須要知足某些條件的。

主要的使用的地方和例子:通知Notificatio的發送,短消息SmsManager的發送和警報器AlarmManager的執行等等。

Android的狀態欄通知(Notification)android

若是須要查看消息,能夠拖動狀態欄到屏幕下方便可查看消息。網絡

步驟:ide

1獲取通知管理器NotificationManager,它也是一個系統服務函數

2創建通知Notification notification = new Notification(icon, null, when);this

3爲新通知設置參數(好比聲音,震動,燈光閃爍)spa

4把新通知添加到通知管理器.net

發送消息的代碼以下:code

//獲取通知管理器component

NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)對象

int icon = android.R.drawable.stat_notify_chat;

long when = System.currentTimeMillis();//通知發生的時間爲系統當前時間

//新建一個通知,指定其圖標和標題

Notification notification = new Notification(icon, null, when);//第一個參數爲圖標,第二個參數爲短暫提示標題,第三個爲通知時間

notification.defaults = Notification.DEFAULT_SOUND;//發出默認聲音

notification.flags |= Notification.FLAG_AUTO_CANCEL;//點擊通知後自動清除通知

Intent openintent = new Intent(this, OtherActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, openintent, 0);//當點擊消息時就會向系統發送openintent意圖

notification.setLatestEventInfo(this, 「標題」, 「我是內容", contentIntent);

mNotificationManager.notify(0, notification);//第一個參數爲自定義的通知惟一標識

 

重點是setLatestEventInfo( )方法的最後一個參數!!!!它是一個PendingIntent!!!!!!!!!

這裏使用到了PendingIntent(pend本意是待定,不肯定的意思)

PendingIntent能夠看做是對Intent的包裝。PendingIntent主要持有的信息是它所包裝的Intent和當前Application的Context。正因爲PendingIntent中保存有當前Application的Context,使它賦予帶他程序一種執行的Intent的能力,就算在執行時當前Application已經不存在了,也能經過存在PendingIntent裏的Context照樣執行Intent。

 

PendingIntent的一個很好的例子:

SmsManager的用於發送短信的方法:

sendTextMessage(destinationAddress, scAddress, text, sentIntent, deliveryIntent);

第一個參數:destinationAddress對方手機號碼

第二個參數:scAddress短信中心號碼通常設置爲空

第三個參數:text短信內容

第四個參數:sentIntent判斷短信是否發送成功,若是你沒有SIM卡,或者網絡中斷,則能夠經過這個itent來判斷。注意強調的是「發送」的動做是否成功。那麼至於對於對方是否收到,另當別論

第五個參數:deliveryIntent當短信發送到收件人時,會收到這個deliveryIntent。即強調了「發送」後的結果

就是說是在"短信發送成功"和"對方收到此短信"纔會激活 sentIntent和deliveryIntent這兩個Intent。這也至關因而延遲執行了Intent


上面兩個例子能夠理解,PendingIntent就是一個能夠在知足必定條件下執行的Intent,它相比於Intent的優點在於本身攜帶有Context對象,這樣他就沒必要依賴於某個activity才能夠存在。

//////////////////////////////////////////////////////////////////////////////////////////////

PendingIntent的做用舉例以及和Intent的區別

一、PendingIntent做用

根據字面意思就知道是延遲的intent,主要用來在某個事件完成後執行特定的Action。PendingIntent包含了Intent及Context,因此就算Intent所屬程序結束,PendingIntent依然有效,能夠在其餘程序中使用。
經常使用在通知欄及短信發送系統中。

PendingIntent通常做爲參數傳給某個實例,在該實例完成某個操做後自動執行PendingIntent上的Action,也能夠經過PendingIntent的send函數手動執行,並能夠在send函數中設置OnFinished表示send成功後執行的動做。

二、PendingIntent舉例

a. 系統通知欄

複製代碼
NotificationManager nm = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
int icon = android.R.drawable.stat_notify_chat;
long when = System.currentTimeMillis() + 2000;
Notification n = new Notification(icon, "通知欄demo提醒", when);
n.defaults = Notification.DEFAULT_SOUND;
n.flags |= Notification.FLAG_AUTO_CANCEL;

Intent openintent = new Intent(this, DemoList.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, openintent, PendingIntent.FLAG_CANCEL_CURRENT);
n.setLatestEventInfo(this, "通知欄demo提醒title", "通知欄demo提醒text", pi);
nm.notify(0, n);
複製代碼

setLatestEventInfo表示設置點擊該通知的事件

b. 短信系統舉例

private final static String SEND_ACTION      = "send";
private final static String DELIVERED_ACTION = "delivered";

private void sendSms(String receiver, String text) {
    SmsManager s = SmsManager.getDefault();
    PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(SEND_ACTION),
                                                      PendingIntent.FLAG_CANCEL_CURRENT);
    PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED_ACTION),
                                                           PendingIntent.FLAG_CANCEL_CURRENT);
    // 發送完成
    registerReceiver(new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            switch (getResultCode()) {
                case Activity.RESULT_OK:
                    Toast.makeText(getBaseContext(), "Send Success!", Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    Toast.makeText(getBaseContext(), "Send Failed because generic failure cause.",
                                   Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                    Toast.makeText(getBaseContext(), "Send Failed because service is currently unavailable.",
                                   Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:
                    Toast.makeText(getBaseContext(), "Send Failed because no pdu provided.", Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    Toast.makeText(getBaseContext(), "Send Failed because radio was explicitly turned off.",
                                   Toast.LENGTH_SHORT).show();
                    break;
                default:
                    Toast.makeText(getBaseContext(), "Send Failed.", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }, new IntentFilter(SEND_ACTION));

    // 對方接受完成
    registerReceiver(new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            switch (getResultCode()) {
                case Activity.RESULT_OK:
                    Toast.makeText(getBaseContext(), "Delivered Success!", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    Toast.makeText(getBaseContext(), "Delivered Failed!", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }, new IntentFilter(DELIVERED_ACTION));

    // 發送短信,sentPI和deliveredPI將分別在短信發送成功和對方接受成功時被廣播
    s.sendTextMessage(receiver, null, text, sentPI, deliveredPI);
}

private final static String SEND_ACTION      = "send";
private final static String DELIVERED_ACTION = "delivered";

private void sendSms(String receiver, String text) {
    SmsManager s = SmsManager.getDefault();
    PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(SEND_ACTION),
                                                      PendingIntent.FLAG_CANCEL_CURRENT);
    PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED_ACTION),
                                                           PendingIntent.FLAG_CANCEL_CURRENT);
    // 發送完成
    registerReceiver(new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            switch (getResultCode()) {
                case Activity.RESULT_OK:
                    Toast.makeText(getBaseContext(), "Send Success!", Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    Toast.makeText(getBaseContext(), "Send Failed because generic failure cause.",
                                   Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                    Toast.makeText(getBaseContext(), "Send Failed because service is currently unavailable.",
                                   Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:
                    Toast.makeText(getBaseContext(), "Send Failed because no pdu provided.", Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    Toast.makeText(getBaseContext(), "Send Failed because radio was explicitly turned off.",
                                   Toast.LENGTH_SHORT).show();
                    break;
                default:
                    Toast.makeText(getBaseContext(), "Send Failed.", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }, new IntentFilter(SEND_ACTION));

    // 對方接受完成
    registerReceiver(new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            switch (getResultCode()) {
                case Activity.RESULT_OK:
                    Toast.makeText(getBaseContext(), "Delivered Success!", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    Toast.makeText(getBaseContext(), "Delivered Failed!", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }, new IntentFilter(DELIVERED_ACTION));

    // 發送短信,sentPI和deliveredPI將分別在短信發送成功和對方接受成功時被廣播
    s.sendTextMessage(receiver, null, text, sentPI, deliveredPI);
}

以上的兩個PendingIntent sentPI和deliveredPI將分別在短信發送成功和對方接受成功時被廣播

三、Intent和PendingIntent的區別

a. Intent是當即使用的,而PendingIntent能夠等到事件發生後觸發,PendingIntent能夠cancel
b. Intent在程序結束後即終止,而PendingIntent在程序結束後依然有效
c. PendingIntent自帶Context,而Intent須要在某個Context內運行
d. Intent在原task中運行,PendingIntent在新的task中運行

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

PendingIntent用於描述Intent及其最終的行爲. 
        你能夠經過getActivity(Context context, int requestCode, Intent intent, int flags)系列方法從系統取得一個用於啓動一個Activity的PendingIntent對象,

       能夠經過getService(Context context, int requestCode, Intent intent, int flags)方法從系統取得一個用於啓動一個Service的PendingIntent對象

        能夠經過getBroadcast(Context context, int requestCode, Intent intent, int flags)方法從系統取得一個用於向BroadcastReceiver的Intent廣播的PendingIntent對象

         返回的PendingIntent能夠遞交給別的應用程序,而後繼續處理。這裏的話你能夠稍後才處理PendingIntent中描述的Intent及其最終行爲。

        當你把PendingIntent遞交給別的程序進行處理時,PendingIntent仍然擁有PendingIntent原程序所擁有的權限(with the same permissions and identity).當你從系統取得一個PendingIntent時,必定要很是當心才行。好比,一般,若是Intent目的地是你本身的component(Activity/Service/BroadcastReceiver)的話,你最好採用在Intent中顯示指定目的component名字的方式,以確保Intent最終能發到目的,不然Intent最後可能不知道發到哪裏了。一個PendingIntent就是Android系統中的一個token(節點,這個應該是Linux或C\C++用語)的一個對象引用,它描述了一些將用於retrieve的數據(這裏,這些數據描述了Intent及其最終的行爲)。

        這就意味着即便PendingIntent原進程結束了的話, PendingIntent自己仍然還存在,可在其餘進程(PendingIntent被遞交到的其餘程序)中繼續使用.若是我在從系統中提取一個PendingIntent的,而系統中有一個和你描述的PendingIntent對等的PendingInent, 那麼系統會直接返回和該PendingIntent實際上是同一token的PendingIntent,而不是一個新的token和PendingIntent。然而你在從提取PendingIntent時,經過FLAG_CANCEL_CURRENT參數,讓這個老PendingIntent的先cancel()掉,這樣獲得的pendingInten和其token的就是新的了。

       經過FLAG_UPDATE_CURRENT參數的話,可讓新的Intent會更新以前PendingIntent中的Intent對象數據,例如更新Intent中的Extras。另外,咱們也能夠在PendingIntent的原進程中調用PendingIntent的cancel ()把其從系統中移除掉。

PendingIntent的Flags的類型:  

  1.   * Flags的類型:  
  2.     FLAG_ONE_SHOT:獲得的pi只能使用一次,第二次使用該pi時報錯  
  3.     FLAG_NO_CREATE: 當pi不存在時,不建立,返回null  
  4.     FLAG_CANCEL_CURRENT: 每次都建立一個新的pi  
  5.     FLAG_UPDATE_CURRENT: 不存在時就建立,建立好了之後就一直用它,每次使用時都會更新pi的數據(使用較多)  
  6.   * 在AlarmManager中的使用  
  7.     Intent intent = new Intent("action", null, context, serviceClass);  
  8.         PendingIntent pi = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);  
  9.         AlarmManager manager = (AlarmManager)probe.getSystemService(Context.ALARM_SERVICE);  
  10.         manager.set(AlarmManager.RTC_WAKEUP, milis, pi);  
  11.   * 在NotificationManager中的使用  
  12.     Intent intent = new Intent();  
  13.         intent.setAction("myaction");  
  14.         PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);  
  15.     NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
  16.     Notification n = new Notification();  
  17.         n.icon = R.drawable.ic_launcher;  
  18.         n.when = System.currentTimeMillis();  
  19.         n.setLatestEventInfo(this,"this is title", "this is a message", pi);  
  20.         nm.notify(0, n);  

 

  * send()方法是用,調用PendingIntent.send()會啓動包裝的Intent(如啓動service,activity)

  * cancel()方法是爲了解除PendingIntent和被包裝的Intent之間的關聯,此時若是再調用send()方法,則會拋出CanceledException異常

相關文章
相關標籤/搜索