Android PendingIntent 不能跳转的问题总结

来源:互联网 发布:公知怎么喷中国航母 编辑:程序博客网 时间:2024/06/04 17:41

    PendingIntent可以看作是对Intent的包装,供当前App之外的其他App调用。PendingIntent主要持有的信息是它所包装的Intent和当前App的Context。外部App执行这个PendingIntent时,间接地调用里面的Intent。正由于PendingIntent中保存有当前App的Context,使它赋予外部App一种能力,使得外部App可以如同当前App一样的执行PendingIntent里的Intent,就算在执行时当前App已经不存在了,也能通过存在PendingIntent里的Context照样执行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可以递交给别的应用程序,然后继续处理。

Intent intent = new Intent(context, targetComponent.class);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);


Android Notification 设置 PendingIntent 点击后不能跳转,主要有以下几个原因:

1. 对于getActivity,返回的PendingIntent递交给别的应用程序执行,这样就脱离了原始应用程序所在的task栈。官方文档注释如下:

Retrieve a PendingIntent that will start a new activity, like calling Context.startActivity(Intent). Note that the activity will be started outside of the context of an existing activity, so you must use the Intent.FLAG_ACTIVITY_NEW_TASK launch flag in the Intent. 
getActivity最后的flag参数要设置成Intent.FLAG_ACTIVITY_NEW_TASK,才能成功启动PendingIntent中包含的activity。

2. 对于getBroadcast,因为PendingIntent是递交给别的应用程序执行,所以接收Broadcast的receiver必须设置“export=true”,才能接收到广播。但是有些手机上,经过测试即使“export=false”也还是能接收到广播,可能是OEM厂商对系统有所修改。但是建议最好设置成“export=true”。

<receiver    android:name=“xxxxReceiver"   android:exported=“true”>   <intent-filter>       <action android:name=“xxxxx”/>   </intent-filter></receiver>
3. 在设定PendingIntent时第四个参数flag值时,一定要细心理解:

  • FLAG_CANCEL_CURRENT:如果当前系统中已经存在一个相同的PendingIntent对象,那么就将先将已有的PendingIntent取消,然后重新生成一个PendingIntent对象。
  • FLAG_NO_CREATE:如果当前系统中不存在相同的PendingIntent对象,系统将不会创建该PendingIntent对象而是直接返回null。
  • FLAG_ONE_SHOT:该PendingIntent只作用一次。在该PendingIntent对象通过send()方法触发过后,PendingIntent将自动调用cancel()进行销毁,那么如果你再调用send()方法的话,系统将会返回一个SendIntentException。
  • FLAG_UPDATE_CURRENT:如果系统中有一个和你描述的PendingIntent对等的PendingInent,那么系统将使用该PendingIntent对象,但是会使用新的Intent来更新之前PendingIntent中的Intent对象数据,例如更新Intent中的Extras。

4. 当发送两个包含相同的PendingIntent的Notification,发现其中一个可以点击触发,第一个点击没有任何反应。

创建一个PendingIntent对象,都是通过getActivity、getBroadcast、getService方法来获取的。如果传递给getXXX方法的Intent对象的Action是相同的,Data也是相同的,Categories也是相同的,Components也是相同的,Flags也是相同的),如果之前获取的PendingIntent对象还有效的话,那么后获取到的PendingItent并不是一个新创建的对象,而是对前一个对象的引用。

如果我们只是想通过设置不同的Extra来生成不同的PendingIntent对象是行不通的,因为PendingIntent对象由系统持有,并且系统只通过刚才在上面提到的几个要素来判断PendingIntent对象是否是相同的,那么如果我们想在每次更新PendingIntent对象的话,怎么做呢?

  • 在调用getXXX方法之前,先调用NotificationManager.cancel(notifyId)方法,将之前发送的PendingIntent对象从系统中移除
  • 也可以在调用getXXX方法时,将第二参数RequestCode设置成不同的值,这样每次就会创建新的PendingIntent对象

0 0
原创粉丝点击