Android 如何设置 Notification 中PendingIntent 的 Intent

 今天在写完 “ Android Notification 的使用 ” 的时候,发现有几个问题,特别是设置Notification的Intent使之能够像 QQ 或其他程序一样能够正确回调到之前已经放置在后台的Task中的对应Activity,而不是创建它的一个新实例。当然重点便是如何设置该 Activity 的 launchMode 与 Intent 的 Flags 了,说到这里,我不得不说一下今晚的调试经历,当然这里所说的所有的Notification都设置了FLAG_ONGOING_EVENT。

  按照 “ (转载)Android下Affinities和Task ”一文所说的,我们不难得出这样的结论:

  1、设置当用户触发Notification时所发出的Intent,如果设置 FLAG_ACTIVITY_CLEAR_TOP 与 FLAG_ACTIVITY_NEW_TASK ,而launchMode保持不变(即默认为:standard),则当用户用手点击Notification时,此时匹配到后台的Task,并把在堆栈中对应要启动的Activity之前的所有Activity全部清除掉,并且由于 standard 默认对于新的Intent总是创建新的Activity对象。因此存在于该Task中旧的Activity也会被清除掉,然后在该Task中创建新的
Activity对象。

  2、设置当用户触发Notification时所发出的Intent,如果设置 FLAG_ACTIVITY_CLEAR_TOP 与 FLAG_ACTIVITY_NEW_TASK,而launchMode设置为singleTop,则当用户用手点击Notification时,同1一样,只是存在于该Task中旧的Activity不会被清除掉,此时Intent传递给已经存在的Activity并不会创建新的Activity。

  上面得出的结论,经过返回测试,1是正确的,2却存在着很莫名奇妙的问题

  假设现在有个程序X,有2个Activity,分别是 A , B ,其中 A 是 设置了android.intent.action.MAIN的Activity(入口Activity),两者的launchMode都为默认的 standard,创建该Intent的代码如下:

  Intent intent = new Intent(this, A.class);

  intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);

  很明显我们设置的是当用户点击 Notification 时,应该出现的是 A Activity,但无论如何按home键退出当前Task,并使之成为后台Task,在从程序列表启动该程序总能恢复到Task顶端的Activity 给用户,如

当前 B,按home键,在从程序列表启动 X ,这个时候出现的Activity任然是 B,但按照如下的方法操作却会使得从程序列表启动 X,出现的是新创建的A Activity,其中经过Log打印得知下面的所有Activity都在同一个Task中

  1、打开程序出现A,从A startActivity 到B,按Home键,点Notification出现A,再从A startActivity 到 B,按Home键,从程序列表打开程序 出现新创建的实例A

  2、打开程序出现A,从A startActivity 到B,点Notification出现A,再从A startActivity 到B,按Home键,从程序列表打开程序也出现了新创建的实例A

  这里所说的“新创建的实例A”都是创建在同一Task中的新的A Activity实例,也就是说按照以上两种方法,再按返回键,出现的则是 B,再按返回键出现的则是 A。这里我实在想不出为什么会在同一Task中创建一个新的Activity,就算从程序列表打开程序的Intent使用了 FLAG_ACTIVITY_NEW_TASK标记,我也不知道为什么,如果有朋友知道,一定要告诉我。

  到这里,我开始发现 从程序列表启动 的优越性,因为不管是在什么时候按Home,再次从程序列表启动时,总能返回到Task的栈顶Activity。起初我想过一个办法,便是重载 Activity写一个类实现当onResume的时候更新Notification,然后我的所有Activity类都直接从该类继承,使得当按 Home 之后总能让Notification记住Task的栈顶Activity,就像QQ一样,但这种方法当然有点牵强,于是我开始看SDK
中 有关Home的Simple,终于发现了如果使用如下的Intent,便不会调用对应的Activity,而是调用Task中的栈顶Activity

  Intent intent = new Intent(Intent.ACTION_MAIN);

  intent.addCategory(Intent.CATEGORY_LAUNCHER);

  intent.setClass(this, Main.class);

  intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

  除了 setClass 可以换成使用 setClassName 绑定,FLAG_ACTIVITY_RESET_TASK_IF_NEEDED可以不设,其他的选项都缺一不可。设置ACTION_MAIN与 CATEGORY_LAUNCHER是把该Intent发给了系统对应创建程序的模块,然后系统该模块根据设定的包与类信息还有flags进行处理。当然所有的Intent工作原理都是这样,只是对 ACTION_MAIN - CATEGORY_LAUNCHAR 的处理较为特殊,使得总是显示Task栈顶的Activity而不是setClass设定的Activity类。

时间: 2024-10-31 17:59:10

Android 如何设置 Notification 中PendingIntent 的 Intent的相关文章

Android中pendingIntent与Intent的深入分析

Android中pendingIntent的深入分析 pendingIntent字面意义:等待的,未决定的Intent. 要得到一个pendingIntent对象,使用方法类的静态方法 getActivity(Context, int, Intent, int),getBroadcast(Context, int, Intent, int),getService(Context, int, Intent, int)  分别对应着Intent的3个行为,跳转到一个activity组件.打开一个广播

Android实现为Notification加上一个进度条的方法_Android

本文实例讲述了Android实现为Notification加上一个进度条的方法.分享给大家供大家参考,具体如下: package com.notification; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Intent;

Android实现为Notification加上一个进度条的方法

本文实例讲述了Android实现为Notification加上一个进度条的方法.分享给大家供大家参考,具体如下: package com.notification; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Intent;

android如何在fragment中设置屏幕的上半部分区域有触摸事件?

问题描述 android如何在fragment中设置屏幕的上半部分区域有触摸事件? 我设置了一个swiperefreshlistview,但是列表刷新的touch方法跟列表的滑动冲突了,请问下在fragment中怎么设置区域监听的 解决方案 列表布局是占满整个fragment么?如果不是的话,可以在xml布局中对部分区域设置点击无效,如果是占满fragment的话,但是想对其中一块区域监听,那就直接在代码中判断是否在那个区域范围内再做操作了 解决方案二: 在fragment上部分添加一个view

动态-android如何在代码中给组件设置style?

问题描述 android如何在代码中给组件设置style? RT,不要提TextView了,全部都是告诉我TextView.setTextAppearance(),我要的是别的组件,比如LinearLayout之类的,如何在代码中设置他的style 我看了下源代码,style都是在初始化的时候通过TypedArray解析style然后一条条属性加进去的,那么有没有类似style这样的方法,可以动态设置的 没有C币了,多多包涵下,谢谢了 解决方案 参考Android: set view style

布局-Android自定义控件在scrollview中设置高度不起作用,已经重写了 onMeasure方法

问题描述 Android自定义控件在scrollview中设置高度不起作用,已经重写了 onMeasure方法 布局: android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true"> <RelativeLayout android:layout_width="match_parent&q

Android开发之Notification通知用法详解_Android

本文实例讲述了Android开发之Notification通知用法.分享给大家供大家参考,具体如下: 根据activity的生命周期,在activity不显示时,会执行onStop函数(比如按下home键),所以你在onStop函数(按退出键除外)里面把notification放在通知栏里,再此显示时,把notification从通知栏里去掉.或者,只要程序在运行就一直显示通知栏图标. 下面对Notification类中的一些常量,字段,方法简单介绍一下: 常量: DEFAULT_ALL 使用所

Android编程自定义Notification实例分析_Android

本文实例讲述了Android编程自定义Notification的用法.分享给大家供大家参考,具体如下: Notification是一种让你的应用程序在不使用Activity的情况下警示用户,Notification是看不见的程序组件警示用户有需要注意的事件发生的最好途径. 作为UI部分,Notification对移动设备来说是最适合不过的了.用户可能随时都带着手机在身边.一般来说,用户会在后台打开几个程序,但不会注意它们.在这样的情形下,当发生需要注意的事件时,能够通知用户是很重要的. Noti

Android闹钟设置的解决方案_Android

Android设置闹钟并不像IOS那样这么简单,做过Android设置闹钟的开发者都知道里面的坑有多深.下面记录一下,我解决Android闹钟设置的解决方案.主要问题1.API19开始AlarmManager的机制修改. 2.应用程序被Kill掉后,设置的闹钟不响. 3.6.0以上进入Doze模式会使JobScheduler停止工作. 4.手机设置重启后,闹钟失效问题. API19以上AlarmManager机制的修改 API19之前AlarmManager提供了三个设置闹钟的方法,由于业务需求