如何检测我的任何活动是否处于前台并对用户可见?

25
我希望当我的任何活动可见时,能够启动一个意图(Intent),否则将其作为通知提醒,并由用户触发。
为了做出这样的决定,我需要知道是否有任何一个我的活动在前台显示,该怎么做呢?
5个回答

10

我不知道有一种方法可以获得当前显示的活动,但是您可以结合Activity 生命周期和一个标志来实现。

对于标志,如果您已扩展了Application类,则那可能是存储它的不错位置。有关扩展应用程序类的信息,请参阅此问题的顶部答案。(d)

因此,在onResume / onPause或onStart / onStop中跟踪当前活动(或指示活动可见的标志)可能是合适的,具体取决于您想要的行为。

由于您有多个活动,因此需要一个中心点来存储标志,这就是为什么应用程序是有意义的原因。您可以通过将应用程序上下文转换为自定义应用程序对象(例如((MyApplication)getApplicationContext()).isMyActivityActive)来获取自定义应用程序对象。

您还可以扩展Activity,以帮助保持代码整洁且紧凑。


如果您正在使用服务,则可以在每个活动的onStart / onStop(或onResume / onPause)中绑定到该服务。如果已绑定,则可见。


1
并非所有情况下都是如此。例如,当您获取唤醒锁PROXIMITY_SCREEN_OFF_WAKE_LOCK时,为了模拟呼叫模式的行为,在屏幕关闭或打开时,当用户将手机靠近耳朵时,这是期望的行为,例如编写VoIP应用程序。但是,当用户将手机靠近头部并且屏幕被阻挡时,就会调用onPause,相反则会调用onResume。问题在于,您不知道为什么会调用它,因此您不知道是否应该暂停应用程序。因此,可能会发生其他事件,可能导致调用onPause或onResume。 - Krzysztof Cichocki

4
你可以向ActivityManager请求正在运行的任务:
ActivityManager activityManager = (ActivityManager)getContext()
                .getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> runningTasks = activityManager.getRunningTasks(Integer.MAX_VALUE));

根据API文档:

返回当前正在运行的任务列表,最近的任务排在第一位,之后是旧的任务。

因此,列表中的第一项是最前面的活动。


14
同时根据 API 文档:注意:此方法仅用于调试和展示任务管理用户界面。在应用程序的核心逻辑中不应该使用它,比如基于此处信息来决定不同行为。这样的使用是不被支持的,而且将来很可能会失效。例如,如果多个应用程序可以同时运行,那么基于此处数据意义进行控制流程的假设将是不正确的。 - Edward Dale

2

你可以使用onWindowFocusChanged(boolean hasFocus)方法,将其放置在你的活动(activity)的超类中,以便在它获得焦点时启动意图(intent)。


这很好,但你需要自定义对话框,因为根据文档,对话框会导致 onWindowFocusChanged(bool) 告诉你该活动不可见。因此,在这种情况下,它似乎不是一个好的解决方案。你更关心应用程序是否在前台而不是可见。 - Justin

2

onResume()被调用且onPause()未被调用 = 可见。
在您的Application子类中拥有一个public static Activity currentlyVisible;,该变量将由您的活动更新(在onResume()中设置为实例,在onPause()中设置为null)。或者发明一种不那么丑陋的注册表变体。


5
不应该像那样持有对Activity对象的引用...请参阅http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html。 - cristis
一般来说 - 是的。除非你在太晚之前手动将其设置为 null 引用。 - yanchenko
因为Activity.isResumed或Activity.isStarted太容易了... :-) - GenesisST

0

除了使用活动管理器外,您可以通过代码实现一个简单的技巧。如果您仔细观察活动周期以及两个活动之间和前台到后台之间的流程,则如下所示。假设A和B是两个活动。

从A到B的转换时:1.调用A的onPause()方法 2.调用B的onResume()方法 3.当B完全恢复时,调用A的onStop()方法

当应用程序进入后台时:1.调用A的onPause()方法 2.调用A的onStop()方法

您可以通过在活动中放置标志来检测后台事件。

创建一个抽象活动并将其从其他活动中扩展,这样您就不必将代码复制粘贴到任何需要后台事件的所有其他活动中。

在抽象活动中创建标志isAppInBackground。

在onCreate()方法中:isAppInBackground = false;

在onPause()方法中:isAppInBackground = false;

在onStop()方法中:isAppInBackground = true;

您只需在onResume()中检查isAppInBackground是否为true即可。 检查完您的标志后,再次将isAppInBackground = false

为了在两个活动之间进行过渡,因为第一个活动的onStop()总是在第二个活动恢复后调用,所以标志永远不会为真。当应用程序处于后台时,activity的onStop()将立即在onPause()之后被调用,因此当您稍后打开应用程序时,标志将为真。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接