首页 > 代码库 > PendingIntent详解
PendingIntent详解
PendingIntent详解
http://blog.csdn.net/hudashi/article/details/7060837
ppWidget(二) PendingIntent
关于android中PendingIntent.getBroadcase的注册广播
1)什么是PendingIntent
PendingIntent和Intent略有不同,它可以设置执行次数,主要用于远程服务通信、闹铃、通知、启动器、短信中,在一般情况下用的比较少。
2)PendingIntent什么用
Notification支持多种Intent来响应单击事件、消除事件、处理紧急状态的全屏事件等。
这里就用到了setContentIntent(PendingIntent intent)来处理以上这么多的事件。
这边就是 把 PendingIntent 交给 Notification 通知栏 这个程序,当 Notification 通知栏 执行 点击事件后,执行 PendingIntent 这个意图。
3)相关属性和方法
属性:
PendingIntent的位标识符:
FLAG_ONE_SHOT 表示返回的PendingIntent仅能执行一次,执行完后自动取消。 在该PendingIntent对象通过send()方法触发过后,PendingIntent将自动调用cancel()进行销毁,那么如果你再调用send()方法的话,系统将会返回一个SendIntentException。
FLAG_NO_CREATE 表示如果描述的PendingIntent不存在,并不创建相应的PendingIntent,而是返回NULL
FLAG_CANCEL_CURRENT 表示相应的PendingIntent已经存在,则取消前者,然后创建新的PendingIntent,这个有利于数据保持为最新的,可以用于即时通信的通信场景 FLAG_UPDATE_CURRENT 表示更新的PendingIntent。 如果之前的PendingIntent有多个属性,当前改了其中一个属性,那么这个PendingIntent只更新当前的属性,其他没有改变的属性 不更新
PendingIntent 是系统用于检索原始数据的一个标记,即使一个application停止了,但如果又新建application , 检索个相同intent的PendingIntent 它将和原来的PndingIntent 拥有相同的标记, 必须通过remove 移除它,否者可能会出现该应用出现上次应用的数据。
PendingIntent 可以通过getService,getActivity,getBroadcast 来启动相应的组件
=============================================
从系统取得一个用于启动一个Activity的 PendingIntent对象,
=============================================
从系统取得一个用于启动一个Service的 PendingIntent对象
用Intent实例化一个PendingIntent,利用PendingIntent的getService方法来启动一个服务
=============================================
从系统取得一个用于向BroadcastReceiver的发送Intent广播的 PendingIntent对象 (广播 事先要在代码中先注册,或者直接在清单文件中注册)
=============================================
因为对于Context的startActivity方法,如果不是在其子类(Activity)中调用,那么必须对Intent加上FLAG_ACTIVITY_NEW_TASK。
开启Service
/** * 1、定义一个intent来开启Service * 注:参数为开启Service的动作 */ Intent startServiceInten=new Intent("zyf.temp.Service.START"); /** * 2、用Intent实例化一个PendingIntent,利用PendingIntent的getService方法来启动一个服务 */ PendingIntent pfullintent= PendingIntent.getService(context, 0, startServiceInten, 0); /** * 实例化RemoteView,其对应相应的Widget布局 */ RemoteViews views= new RemoteViews(getPackageName(), R.layout.widget); /** * 4、给RemoteView上的Button或ImageButton设置按钮事件 */ views.setOnClickPendingIntent(R.id.IBfullscreen, pfullintent);
例如:Mp3 中多个button绑定pendingIntent 事件:
@Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { System.out.println("onUpdate"); for(int i=0;i<appWidgetIds.length;i++){ //创建一个Intent对象 RemoteViews remoteViews=new RemoteViews(context.getPackageName(),R.layout.appwidget_music); //前一首歌 Intent intent=new Intent( MUSIC_PLAY_STATE); Bundle bundle=new Bundle(); bundle.putString("action","prev"); bundle.putInt(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetIds[i]); intent.putExtras(bundle); // 创建一个PendingIntent对象 PendingIntent pendingIntent=PendingIntent.getBroadcast(context,0,intent, PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.prevMusicImage,pendingIntent); //下一首 intent=new Intent( MUSIC_PLAY_STATE); bundle=intent.getExtras(); bundle=new Bundle(); bundle.putString("action","next"); bundle.putInt(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetIds[i]); intent.putExtras(bundle); pendingIntent=PendingIntent.getBroadcast(context,1,intent,PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.nextMusicImage,pendingIntent); //播放或暂停 intent=new Intent( MUSIC_PLAY_STATE); bundle=new Bundle(); bundle.putString("action","playOrPause"); intent.putExtras(bundle); pendingIntent=PendingIntent.getBroadcast(context,2,intent,PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.playOrPauseImage,pendingIntent); System.out.println("appWidgetIds======"+appWidgetIds[i]); appWidgetManager.updateAppWidget(appWidgetIds[i],remoteViews); } super.onUpdate(context, appWidgetManager, appWidgetIds); }
例如: 签到红包的广播
/** * 签到红包的广播 意图。 * 这个广播 是在清单文件中注册的 * @return */ private PendingIntent initRedBagIntent() { Intent intent =new Intent(WifiApplication.getInstance(), RedBagNotiReceiver.class); intent.setAction("com.wifibanlv.action.GET_REDBAG_Notification"); PendingIntent operation = PendingIntent .getBroadcast(WifiApplication.getInstance(), 0, intent, 0); return operation; }
PendingIntent 发送一个广播,执行 发送一个通知栏的事件。
/** * 设置开启 签到红包的广播 * @author Administrator * */public class RedBagNotiReceiver extends BroadcastReceiver { private Context mContext; private Logger logger = LoggerFactory.getLogger(LoggerKind.WH_LOGGER, AuthorType.ZhiQi, "AAAA"); @Override public void onReceive(Context context, Intent intent) { mContext = context; logger.d("红包通知的广播 " + intent.getAction() + " , " + intent.getDataString()); //intent.getDataString() 好像是包名 showNotification(); } ....}
点击通知栏,通过 PendingIntent 打开一个应用
PendingIntent contentItent = PendingIntent.getActivity(mContext, 0, runApp(WIFIBL.WIFIBL_PACKAGENAME), 0); notification.flags |= Notification.FLAG_AUTO_CANCEL; notification.setLatestEventInfo(mContext, contentTitle, contentText, contentItent); // 把Notification传递给NotificationManager notificationManager.notify(0, notification);
private Intent runApp(String packageName) { // 法一 : 但 只会获得用户安装程序的意图,如果是系统的应用程序,都会获取失败 // getPackageManager().queryIntentActivities(intent, flags); try { // PackageManager.GET_ACTIVITIES 解析Activity 节点 , 获取 详细信息。 在 该应用程序的清单文件中的 Activity节点 PackageInfo itemPackageInfo = mContext.getPackageManager().getPackageInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_ACTIVITIES); //得到所有的Activity 信息的数组。 数组存放的是 当前包里面 所有的Activity 节点信息。 //数组中第一个元素,具有启动属性的Activity。 所以 需要 "PackageManager.GET_ACTIVITIES" 解析节点。解析是很耗时的 ActivityInfo[] activityinfos = itemPackageInfo.activities; //系统有一般的应用程序 是不具备启动节点的功能。 所以 判断 下面获得的Activity数组 长度大于0,才可以运行。 if (activityinfos.length > 0) { /** * 激活 一个意图 让 应用程序 运行 * 数组中第一个元素,具有启动属性的Activity */ ActivityInfo startActivity = activityinfos[0]; String className = startActivity.name; for (ActivityInfo activity : activityinfos) { if (activity.name.equals("com.wifibanlv.www.activity.MainViewPagerActivity")) { className = "com.wifibanlv.www.activity.MainViewPagerActivity"; } } Intent intent = new Intent(); intent.setClassName(packageName, className); if(className.equals("com.wifibanlv.www.activity.MainViewPagerActivity")) { intent.putExtra("OffscreenPage", MainViewPagerActivity.OFFSCREEN_PAGE_WAI); } return intent; // mContext.startActivity(intent); } else { Toast.makeText(mContext, "该应用无法运行", 0).show(); } } catch (Exception e) { Toast.makeText(mContext, "应用程序无法启动", 0).show(); e.printStackTrace(); } return null; }
PendingIntent详解