如何从后台以编程方式恢复Android Activity

情况:

  1. 假设我目前正在推出应用程序活动A.
  2. 过了一段时间我按“主页”按钮。 应用程序A转到后台。
  3. 这时,我开始使用另一个应用程序B – 例如youtube等。
  4. 在应用程序A中发生了一些事情(在这个上下文中无关紧要,假设计时器已完成计算时间),该应用程序A当前被最小化为背景。
  5. 在事件发生时,应用程序A活动自动从后台恢复。

题:

如何完成第5步? 基本上我需要知道如何以编程方式从后台恢复应用程序。

我试图启动意图“重启”我的应用程序活动,但它没有奏效:

Intent intent = new Intent(context, MainActivity.class); intent.setAction(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); context.startActivity(intent); 

我的清单文件:

                                                     

为了将您的应用程序带到前台,您必须从另一个上下文( ServiceBroadcastReceiver )调用startActivity() )。 只是从Activity调用startActivity()不会将您的应用程序带到前台。

您的Intent不需要ACTION和CATEGORY,但您需要设置Intent.FLAG_ACTIVITY_NEW_TASK

如果您的活动处于不同的任务中,则可以使用此操作将活动的任务置于前台:

 ActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); activityManager.moveTaskToFront(getTaskId(), ActivityManager.MOVE_TASK_NO_USER_ACTION); 

你需要android.permission.REORDER_TASKS才能这样做。 它甚至可以在Android M中运行,但是在某些情况下从服务中获取意图会更好。

只需建立一个服务,在后台做任何你想做的事。 甚至更好:在后台执行某些操作,使用侦听器监听,在您等待的事件发生时立即绑定服务(计时器等)。 既然你在服务中,你只需调用应该在前台的Activity,就像你在其他任何地方一样:

 Intent i = new Intent(MyService.this, MyActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); MyService.this.startActivity(i); 

David Wasser的回答有助于解决我的问题。

我的Activity在前台Service运行,所以我不得不从该Service上下文中调用startActivity()方法。

 Intent intent = new Intent(context, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mServiceContext.startActivity(intent); 

以编程方式从后台恢复应用程序将

让您的活动FOREGROUND,用户在BACKGROUND中的当前活动。 用户的工作是GONE

从用户的角度来看,这不是正确的行为。 此外,如果我们以编程方式恢复活动,活动生命周期将被破坏。 活动状态将丢失。

替代方案

当你的计时器,任务(任何东西)在后台完成时,你可以提供NOTIFICATION 。 如果用户有兴趣检查您的活动,那么他/她可以在不中断当前工作的情况下查看通知

我认为最好的方法是通过IntentService。 它也是这样的,它可能是最简单的方法。 所以顺序是:在Activity中注册一个接收器(在onCreate中)来监听你想要的事件,然后当接收者获得事件时,它以标准方式启动一个IntentService,然后启动Activity。
这样它就可以将应用程序放在其他应用程序之前,包括活动应用程序和隐藏应用程序。 (但是这应该谨慎使用。通常情况下,用户不会喜欢在他正在使用的应用程序前弹出另一个应用程序,除非有很好的理由。)
在我的KitKat设备(4.4.x)上,我对它进行了测试, 只有在没有其他应用程序打开的情况下 ,我才可以通过从Activity中的接收器调用startActivity来将应用程序带到前面,即我的应用程序隐藏在主屏幕下。 然后它将成为最重要的。 如果另一个应用程序是打开的,即使它也是隐藏的(但在我的应用程序前面;我实际上没有测试看看如果两个应用程序都被隐藏而且我的是在前面会发生什么,但这不是很重要),那么它赢了如果从同一个活动中开始,它就会出现在顶部。 因此,为了使它总是弹出你需要使用IntentService(或其他方式,但据我所知,这是最简单的一个)。