Notification点击跳转到消息界面返回到主界面Bug解决

需求:

点击消息通知栏(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数组给

	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));

看一下API中对于这个方法的解释:

public static PendingIntent getActivities (Context context, int requestCode, Intent[] intents, int flags, Bundle options)
Added in  API level 16

Like getActivity(Context, int, Intent, int), 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 togetActivity(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 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 getActivity(Context, int, Intent, int), its content will be the subject of replacement by send(Context, int, Intent) and 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 Intent objects you supply here should almost always be explicit intents, that is specify an explicit component to be delivered to through 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_SHOTFLAG_NO_CREATEFLAG_CANCEL_CURRENTFLAG_UPDATE_CURRENT, or any of the flags as supported by Intent.fillIn() to control which unspecified parts of the intent that can be supplied when the actual send happens.
Returns
  • Returns an existing or new PendingIntent matching the given parameters. May return null only if FLAG_NO_CREATE has been supplied.

从上面的意思中可以看出,数组中第一个Intent对象将会被额外的启动一个栈,于是,我就将MainActivity设置为intent[0]对象.

而intent数组中最后一个,将作为PendIntent的关键,也就是点击之后需要跳转的第一个类文件


所以,再调用了PendingIntent.getActivities之后,还需要给第一个Intent[]数组最后的一个Activity(在我这里是MsgActivity)设置一下启动模式,

因为Intent[0] 对象(MainActivity)和MsgActivity不处于同一个栈中,于是我就将MsgActivity设置一个属性:  android:excludeFromRecents="true",将它从最近运行的程序里面不显示。


综上所述,完整的代码如下:

	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;
	}

这个时候还需要给Mainfest.xml清单文件中给MsgActivity设置一下属性:

        <activity
            android:name="com.baimi.dujiangyan.activity.MsgActivity"
            android:excludeFromRecents="true"
            android:launchMode="singleTask"
            android:taskAffinity="" >


MainActivity的启动模式记得是要SingleTop。


在网上也有说可以采用: android:allowTaskReparenting 属性来解决。但是这个我测试过,也无效。可能和机型有关系。

上述的功能以及解决方案全是在小米平板2带上出现的,安卓5.1.1的系统。



  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值