1. PendingIntent作用
根据字面意思就知道是延迟的intent,主要用来在某个事件完成后执行特定的Action。要得到一个pendingIntent对象,使用方法类的静态方法 getActivity(Context, int, Intent, int),getBroadcast(Context, int, Intent, int),getService(Context, int, Intent, int) 分别对应着Intent的3个行为,跳转到一个activity组件、打开一个广播组件和打开一个服务组件。PendingIntent包含了Intent及Context,所以就算Intent所属程序结束,PendingIntent依然有效,可以在其他程序中使用。常用在通知栏及短信发送系统中。
PendingIntent一般作为参数传给某个实例,在该实例完成某个操作后自动执行PendingIntent上的Action,也可以通过PendingIntent的send函数手动执行,并可以在send函数中设置OnFinished表示send成功后执行的动作。
2. PendingIntent举例
a) 系统通知栏
NotificationManagernm = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
inticon = android.R.drawable.stat_notify_chat;
longwhen = System.currentTimeMillis() + 2000;
Notificationn = new Notification(icon, "通知栏demo提醒", when);
n.defaults= Notification.DEFAULT_SOUND;
n.flags= Notification.FLAG_AUTO_CANCEL;
Intentopenintent = new Intent(this, DemoList.class);
PendingIntentpi = 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 StringSEND_ACTION = "send";
private final static StringDELIVERED_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 voidonReceive(Context context, Intent intent) {
switch(getResultCode()) {
caseActivity.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;
caseSmsManager.RESULT_ERROR_NO_SERVICE:
Toast.makeText(getBaseContext(),"Send Failed because service is currently unavailable.", Toast.LENGTH_SHORT).show();
break;
caseSmsManager.RESULT_ERROR_NULL_PDU:
Toast.makeText(getBaseContext(),"Send Failed because no pdu provided.", Toast.LENGTH_SHORT).show();
break;
caseSmsManager.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()) {
caseActivity.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将分别在短信发送成功和对方接受成功时被广播
3. Intent和PendingIntent的区别
Ø Intent是立即使用的,而PendingIntent可以等到事件发生后触发,PendingIntent可以cancel
Ø Intent在程序结束后即终止,而PendingIntent在程序结束后依然有效
Ø PendingIntent自带Context,而Intent需要在某个Context内运行
Ø Intent在原task中运行,PendingIntent在新的task中运行
备注:
当你把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 ()把其从系统中移除掉。