从Notification发通知跳转引发的几个问题

这两天做了一个Notification 通知消息的东西,需要从通知点击调到指定的Activity,一般来说,这个需求挺简单的,直接在通知中添加,一个Intent 然后使用PendingIntent就可以完成需求。问题出现在了需求是要跳转到正在运行的MainActivity中的Fragment中去。结果发现使用原来的方法getIntent去获取数据就获取不到了。经过一通的搜索Google才找到了解决方案,这会特地记录一下。

正常使用一个Notification 打开一个activity:

 NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
        Intent intent = new Intent();
        intent.putExtra(MainActivity.FLAG_MAINACTIVITY, MainActivity.PAGEINDEX_2);
        builder.setContentText("您有新的任务!");
        builder.setContentTitle("这个是标题");
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(),R.mipmap.ic_launcher));
        builder.setDefaults(NotificationCompat.DEFAULT_ALL);
        builder.setPriority(NotificationCompat.PRIORITY_HIGH);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        builder.setContentIntent(pendingIntent);
        Notification notification = builder.build();
        //notification.flags = Notification.FLAG_NO_CLEAR | Notification.DEFAULT_SOUND;
        notificationManager.notify(1, notification);
正常的逻辑在MainActivity中我们可以使用getIntent方法获取到这个通知附带的数据。这里要说明的是这个activity要在没有运行的情况下这样是可以的。当前的MainActivity就是应用的主界面,所以我一直获取不数据。

在stackoverflow找到了一篇文章,差不多和我的情况一样,参考这里我找到了一些解决的方法。

1.notificationIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);  //设置这个参数

2.在MainActivity中重写onNewIntent()方法 。并且设置setIntent().

3. PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); //设置参数

 @Override
    protected void onNewIntent(Intent intent) {
        //super.onNewIntent(intent);
        this.setIntent(intent);
        LogUtils.e("TAG", "main-onNewIntent");
        obtainFragmentIndex = getIntent().getIntExtra(MainActivity.FLAG_MAINACTIVITY, -1);
        setRadioChecked(obtainFragmentIndex);
    }
上面两个方式基本上就解决的这个问题。这样我们遇到的问题就先解决了,然后来看看原因。在上面搜索的文章中有说到,这个是因为我们给Activity设置了一个SingleTask的启动模式。这样正在运行的MAinActivity就不会再启动,所以之前一直没有拿到数据。onNewIntent就是用来解决这个问题的,在onNewIntent中调用setIntent从新设置Intent后我们就可以拿到数据了。总的来说,还是自己太菜,四种启动模式没有搞清楚。

在解决了问题之后又查了一些资料对于上述的几个概念做一些解释:

1.FLAG_ACTIVITY_NEW_TASK

在新任务中启动Activity,如果已经为正在启动的Activity运行任务,则改任务会转到前台并恢复期最后状态,同时Activity会在onNewIntent() 中收到新的Intent。这个就会和SingleTask 的启动模式一样的行为。

2.FLAG_ACTIVITY_SINGLE_TOP

如果正在启动的Activity是当前的Activity(位于返回栈的顶部),则现在实例会接受对onNewIntent()的调用,而不是创建Activity的新实例。这个行为和SingleTop 启动模式相同。

3.FLAG_ACTIVITY_CLEAR_TOP

如果正在启动的Activity已在当前的任务中运行,则会销毁当前任务顶部的所有Activity,并通过onNewIntent()将Intent 传给Activity已恢复的实例(现在位于顶部)而不是启动该Activity的新实例。产生这个行为没有对应的启动模式。

FLAG_ACTIVITY_CLEAR_TOP一般和FLAG_ACTIVITY_NEW_TASK结合使用。一起使用时,通过这些标志,可以找到其他任务中现有的Activity,并将其放入可以从中相应的Intent的位置。

这些事从Android开发文档中找到的。开发文档 中详细介绍了四种启动模式的使用,以及这些参数的关联使用方式。这应该是最好的学习文档了。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章