需求:
点击消息通知栏(Notification),跳转到APP的消息界面(MsgActivity),在MsgActivity做一系列操作之后,用户点击返回键,返回到MainActivity
实现:
采用PendingIntent.getActivity()方法来设置点击之后需要跳转到的Activity。
结果:
点击Notication------>跳转到MsgActivity-------->在MsgActivity做一些业务处理之后----->startActivity(MsgActivity,MainActivity),并杀死MsgActivity---------->在MainActivity按物理返回键------------>返回到桌面-------------->用安卓自带的最近任务程序里面进入到APP------>发现这个时候居然显示的是MsgActivity
显然,上面结果并不是我们预期的。
于是,采用Stack,将所有的Activity加入到自己定义的栈当中,并在启动MainActivity的时候,从栈中移除掉Stack, 结果还是一样。
解决方案:
采用PendingIntent.getActivities()方法来设置点击事件
PendingIntent android.app. PendingIntent.getActivities( Context context, int requestCode, Intent[] intents, int flags)
从上面的方法中,我们看到,需要传入的是一个Intent[]数组。
然后我们就手动构建一个Intent数组给
看一下API中对于这个方法的解释:intents[0] = Intent.makeRestartActivityTask(new ComponentName(context, com.baimi.dujiangyan.activity.MainActivity.class)); intents[1] = Intent.makeRestartActivityTask(new ComponentName(context, com.baimi.dujiangyan.activity.MsgActivity.class));
public static PendingIntent getActivities (Context context, int requestCode, Intent[] intents, int flags, Bundle options)
Added in API level 16
Like
, but allows an array of Intents to be supplied. The last Intent in the array is taken as the primary key for the PendingIntent, like the single Intent given to
getActivity(Context, int, Intent, int)
. Upon sending the resulting PendingIntent, all of the Intents are started in the same way as they would be by passing them to
getActivity(Context, int, Intent, int)
startActivities(Intent[])
.
The first intent in the array 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. (Activities after the first in the array are started in the context of the previous activity in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.)
The last intent in the array represents the key for the PendingIntent. In other words, it is the significant element for matching (as done with the single intent given to
, its content will be the subject of replacement by
getActivity(Context, int, Intent, int)
and
send(Context, int, Intent)
FLAG_UPDATE_CURRENT
, etc. This is because it is the most specific of the supplied intents, and the UI the user actually sees when the intents are started.
For security reasons, the
objects you supply here should almost always be explicit intents, that is specify an explicit component to be delivered to through
Intent
Intent.setClass
Parameters
context The Context in which this PendingIntent should start the activity. requestCode Private request code for the sender intents Array of Intents of the activities to be launched. flags May be ,
FLAG_ONE_SHOT
,
FLAG_NO_CREATE
,
FLAG_CANCEL_CURRENT
, or any of the flags as supported by
FLAG_UPDATE_CURRENT
to control which unspecified parts of the intent that can be supplied when the actual send happens.
Intent.fillIn()
Returns
- Returns an existing or new PendingIntent matching the given parameters. May return null only if
has been supplied.
FLAG_NO_CREATE
从上面的意思中可以看出,数组中第一个Intent对象将会被额外的启动一个栈,于是,我就将MainActivity设置为intent[0]对象.
而intent数组中最后一个,将作为PendIntent的关键,也就是点击之后需要跳转的第一个类文件
所以,再调用了PendingIntent.getActivities之后,还需要给第一个Intent[]数组最后的一个Activity(在我这里是MsgActivity)设置一下启动模式,
因为Intent[0] 对象(MainActivity)和MsgActivity不处于同一个栈中,于是我就将MsgActivity设置一个属性: android:excludeFromRecents="true",将它从最近运行的程序里面不显示。
综上所述,完整的代码如下:
这个时候还需要给Mainfest.xml清单文件中给MsgActivity设置一下属性:public static void showFication(Context context) { NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); NotificationCompat.Builder builder = new NotificationCompat.Builder(context); builder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher)); builder.setSmallIcon(R.drawable.ic_launcher) .setContentTitle(title) .setContentText(message) .setContentIntent(PendingIntent.getActivities(context, requestCode, makeIntentStack(context),PendingIntent.FLAG_UPDATE_CURRENT)); builder.setAutoCancel(true); Notification notification = builder.getNotification(); notification.icon = R.drawable.ic_launcher; notification.defaults = Notification.DEFAULT_ALL; nm.notify(ficationId, notification); } private static Intent[] makeIntentStack(Context context) { Intent[] intents = new Intent[2]; intents[0] = Intent.makeRestartActivityTask(new ComponentName(context, com.baimi.dujiangyan.activity.MainActivity.class)); intents[1] = Intent.makeRestartActivityTask(new ComponentName(context, com.baimi.dujiangyan.activity.MsgActivity.class)); return intents; }
<activity android:name="com.baimi.dujiangyan.activity.MsgActivity" android:excludeFromRecents="true" android:launchMode="singleTask" android:taskAffinity="" >
MainActivity的启动模式记得是要SingleTop。
在网上也有说可以采用: android:allowTaskReparenting 属性来解决。但是这个我测试过,也无效。可能和机型有关系。
上述的功能以及解决方案全是在小米平板2带上出现的,安卓5.1.1的系统。