使用持续通知来允许用户返回到运行Android应用程序

我正在开发一个有很多活动的应用程序。 我想创build一个持久通知(或多或less),说:“AppName – 返回到AppName”,每当我的后台服务正在运行将出现。 创build和处理通知是没有问题的。

现在,用户可以在几个屏幕/活动中的任何一个上,离开应用程序,然后希望通过通知重新进入应用程序。 问题是 ,通知必须有一个意图,启动一个预定的活动 。 我希望通知重新进入应用程序在任何活动在历史堆栈的顶部

我第一次尝试一个丑陋的解决方法是做一个活动(我们称之为“returnFromNotify”),它的唯一工作就是在“onCreate”中“完成”自己。 通知将在应用程序历史logging的范围内打开“returnFromNotify”,然后立即将其自身删除,将用户发回应用程序堆栈中的以前的历史logging状态。 这似乎工作…除非用户使用“后退”完全退出应用程序。 然后,当他们点击通知,“returnFromNotify”加载,然后完成,发回到主屏幕(因为应用程序的历史堆栈中没有任何活动)。

我考虑试图在“returnFromNotify”之前检测历史堆栈中是否有任何内容,如果没有,启动我的主要活动。 我似乎也无法find办法做到这一点。

任何对Java / Android新手的input或build议? 仅供参考,我的主要历史是基于脚本的语言。

Solutions Collecting From Web of "使用持续通知来允许用户返回到运行Android应用程序"

我喜欢最初创build“returnFromNotify”活动的想法,因为可以检测ResumeActivity是否位于堆栈的底部(因此是堆栈中唯一的活动)。

你可以这样做:

将您的ResumeActivity添加到清单并指定noHistory属性:

<activity android:name=".ResumeActivity" android:noHistory="true" /> 

指定noHistory将确保此活动一旦完成就不会停留在堆栈中。 这样你就知道只有一个当前正在运行的ResumeActivity实例会出现在堆栈中。

为了检查应用程序堆栈,您还必须要求GET_TASKS权限:

 <uses-permission android:name="android.permission.GET_TASKS" /> 

现在,您可以使用ActivityManager :: getRunningTasks()来确定ResumeActivity是否是堆栈中的唯一活动:

 public class ResumeActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if(isOnlyActivityInStack()) { //check the application stack //This activity is the only activity in the application stack, so we need to launch the main activity Intent main = new Intent(this, MainActivity.class); main.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(main); } else { //Return the user to the last activity they had open this.finish(); } } /** * Checks the currently running tasks. If this activity is the base activity, we know it's the only activity in the stack * * @return boolean This activity is the only activity in the stack? **/ private boolean isOnlyActivityInStack() { ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); boolean onlyActivityInStack = false; for(RunningTaskInfo tasks : manager.getRunningTasks(Integer.MAX_VALUE)) { if(tasks.baseActivity.getPackageName().equals(this.getPackageName())) { //find this package's application stack if(tasks.baseActivity.getClassName().equals(this.getClass().getName())) { //If the ResumeActivity is the base activity, we know that it is the only activity in the stack onlyActivityInStack = true; break; } } } return onlyActivityInStack; } } 

我知道你在2年前问过这个问题,但是我提供了这个答案,以防其他人遇到这种情况(就像我一样)。 我认为你正在与你最初的解决scheme走在正确的轨道上。

好的,我相信我已经为我的具体情况find了一个令人满意的解决办法 。 我已经添加了一个静态的整数到我的“mainActivity”,每次它的“onCreate”被激发,它增加整数。 每次“onDestroy”被触发,它就会递减。

在我的“returnFromNotify”中,我看看这个静态整数是否大于0.如果是这样,我假设有一个活动的“mainActivity”,并且在“returnFromNotify”中运行“finish”将返回到那里。 否则,它假设用户已经“支持”出来,完成自己,然后使用“startActivity”来启动一个新的“mainActivity”实例。

这不是一个通用的解决scheme,但对我的目的来说,我认为就足够了。 我仍然愿意接受其他答案,如果有人能够在我的逻辑中打出一个漏洞,请这样做 – build设性的批评是值得欢迎的。 谢谢。

我想有没有简单的方法来做到这一点,而不是在mainActivity中添加计数器,我会扩展应用程序 :

那些需要维护全局应用程序状态的基类。 你可以通过在你的AndroidManifest.xml的标签中指定它的名字来提供你自己的实现,当你的应用程序/包的进程被创build时,这个类将会被实例化。

我会认为那里的逻辑有一个方法,如:

 public Intent getIntentForLastActivityShown(); 

当通知项目被点击时被调用。

我的第一种方法是使用SharedPreferences并存储一个名为lastDisplayedActivity的键值对。 然后在每个Activity的onResume (也可能是`onCreate'),你会有这样的一行:

 sharedPreferences.edit().putInteger("lastDisplayedActivity", ReturnFromNotify.THIS_ACTIVITY_NAME); 

换句话说,您存储了一个应用程序范围的variables,用于指示上次显示哪个活动。 然后你只需从SharedPreferences中获取这个variables并启动相应的活动。

我通常使用名为“Launcher”的活动来检查我的应用程序模型的状态,并根据模型规则启动活动(或者做其他事情)。 我把Model对象放在我的Application类中。 模型可以使用首选项来存储它的状态。 我这样做是为了避免活动中的静态字段。