Android 如何确定我的一项活动是否在前台
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2314969/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to determine if one of my activities is in the foreground
提问by Moritz
I have implemented a BroadcastReceiver which is triggered by the AlarmManager. The AlarmManager is initialized on BOOT_COMPLETED. So i have to declare the receiver in the manifest.
我已经实现了一个由 AlarmManager 触发的 BroadcastReceiver。AlarmManager 在 BOOT_COMPLETED 上初始化。所以我必须在清单中声明接收者。
My problem is that i want the BroadcastReceiver only to do something when none of my own activities are in the foreground (aka the user is not interacting with my application). I pull information from a remote server and don't want to notify the user if he is currently in my application anyways.
我的问题是我希望 BroadcastReceiver 只在我自己的活动都没有在前台时做一些事情(也就是用户没有与我的应用程序交互)。我从远程服务器提取信息,并且无论如何都不想通知用户他当前是否在我的应用程序中。
So far i have not managed to find a way to determine if my application is in the foreground. Is there a way to do such thing? The ActivityManager tells me if my application is running but not whether it is in the foreground.
到目前为止,我还没有设法确定我的应用程序是否在前台。有没有办法做这样的事情?ActivityManager 会告诉我我的应用程序是否正在运行,但不会告诉我它是否在前台。
The problem is pretty much the same as described here: Inform Activity from a BroadcastReceiver ONLY if it is in the foreground
问题与此处描述的几乎相同:Inform Activity from a BroadcastReceiver ONLY if it is in the前台
SOLUTION:
解决方案:
After evaluating several solutions i want to quickly outline what i think is the best method to deal with activities in the background/foreground.
在评估了几种解决方案后,我想快速概述我认为处理后台/前台活动的最佳方法。
The preferred way is to register a broadcast receiver in the onResume method of your activity and to deregister it on the activities on onPause. Any service or other background element will than need to send a broadcast intent with a specific action that your activity will intercept.
首选方法是在活动的 onResume 方法中注册广播接收器,并在 onPause 上的活动中取消注册。任何服务或其他后台元素都需要发送带有特定操作的广播意图,您的活动将拦截该行为。
If your activity is in the foreground it will have its intent receiver registered and is able to directly deal with the intent send from your service. If it is not in the foreground it will not receive the intent but the service that invokved the broadcast will know that nobody intercepted its broadcast intent and will be able to deal with that itself. Eg it could than launch the desired activity, show a notification etc.
如果您的活动在前台,它将注册其意图接收器,并能够直接处理从您的服务发送的意图。如果它不在前台,它将不会收到意图,但调用广播的服务将知道没有人拦截其广播意图,并且能够自行处理。例如,它可以启动所需的活动,显示通知等。
回答by Idolon
The following answer: "Is application running in background", summarizes solutions available for background/foreground checking.
以下答案:“应用程序是否在后台运行”,总结了可用于后台/前台检查的解决方案。
Note:
Previously this answer suggested to use ActivityManager.getRunningAppProcesses()
, however that method appeared to be not completely reliable and its usage is discouraged. Check the link above for the details.
注意:
以前此答案建议使用ActivityManager.getRunningAppProcesses()
,但是该方法似乎并不完全可靠,因此不鼓励使用。查看上面的链接了解详细信息。
回答by CommonsWare
Your activity can track its own state as to whether it is in the foreground (set boolean to true
in onStart()
, to false
in onStop()
). Alas, that boolean is not provided to you by Activity
automatically.
您的 Activity 可以跟踪自己的状态,以确定它是否在前台(将 boolean 设置为true
in onStart()
, to false
in onStop()
)。唉,那个布尔值不是Activity
自动提供给你的。
回答by jqpubliq
ActivityManager#getRunningAppProcesses()
returns a List of RunningAppProcessInfo
. Each RunningAppProcessInfo
has a field called importance. importance equal to RunningAppProcessInfo.IMPORTANCE_FOREGROUND
seems to show which activity is actively being observed by the user. There is also RunningAppProcessInfo.IMPORTANCE_VISIBLE
which is lower but might be worth checking out.
ActivityManager#getRunningAppProcesses()
返回一个列表RunningAppProcessInfo
。每个RunningAppProcessInfo
都有一个称为重要性的字段。重要性等于RunningAppProcessInfo.IMPORTANCE_FOREGROUND
似乎表明用户正在积极观察哪些活动。还有RunningAppProcessInfo.IMPORTANCE_VISIBLE
哪个较低,但可能值得一试。
回答by whlk
check out my solution for determining if an activity is in the foreground: http://www.mannaz.at/codebase/android-activity-foreground-surveillance/
查看我的解决方案以确定活动是否在前台:http: //www.mannaz.at/codebase/android-activity-foreground-surveillance/
It should be easy to revert the logic from "in the foreground" to "not in the foreground".
将逻辑从“在前台”恢复为“不在前台”应该很容易。
回答by Pastiche
I have implemented a BroadcastReceiver which is triggered by the AlarmManager. The AlarmManager is initialized on BOOT_COMPLETED. So i have to declare the receiver in the manifest.
My problem is that i want the BroadcastReceiver only to do something when none of my own activities are in the foreground (aka the user is not interacting with my application). I pull information from a remote server and don't want to notify the user if he is currently in my application anyways.
So far i have not managed to find a way to determine if my application is in the foreground. Is there a way to do such thing? The ActivityManager tells me if my application is running but not whether it is in the foreground.
我已经实现了一个由 AlarmManager 触发的 BroadcastReceiver。AlarmManager 在 BOOT_COMPLETED 上初始化。所以我必须在清单中声明接收者。
我的问题是我希望 BroadcastReceiver 只在我自己的活动都没有在前台时做一些事情(也就是用户没有与我的应用程序交互)。我从远程服务器提取信息,并且无论如何都不想通知用户他当前是否在我的应用程序中。
到目前为止,我还没有设法确定我的应用程序是否在前台。有没有办法做这样的事情?ActivityManager 会告诉我我的应用程序是否正在运行,但不会告诉我它是否在前台。
There doesn't seem to be a direct way to determine if one of your activities is the current running foreground activity. However, you can get the desired effect by using an ordered broadcast and two broadcast receivers. One broadcast receiver needs to be registered in OnResume() and unregistered in OnPause(). The 2nd broadcast receiver will be declared in your manifest as you've already done. Set the android:priority for your receivers such that if the dynamically registered receiver is registered, it will receive the intent first, then you can eat the intent so that the broadcast receiver you registered in your manifest is never notified.
似乎没有直接的方法来确定您的一项活动是否是当前正在运行的前台活动。但是,您可以通过使用有序广播和两个广播接收器来获得所需的效果。一个广播接收器需要在 OnResume() 中注册,在 OnPause() 中取消注册。正如您已经完成的那样,第二个广播接收器将在您的清单中声明。为你的接收器设置 android:priority,这样如果动态注册的接收器被注册,它会首先接收意图,然后你可以吃掉这个意图,这样你在清单中注册的广播接收器就不会收到通知。
回答by klimat
I'd use ActivityLifecycleCallbacksto get much cleaner solution.
我会使用ActivityLifecycleCallbacks来获得更清洁的解决方案。
It canbe insecure, read thisbefore you decided to use example below in production. It works in 'home development' for my device and OS version.
它可能不安全,请在决定在生产中使用下面的示例之前阅读此内容。它适用于我的设备和操作系统版本的“家庭开发”。
public class App extends Application implements Application.ActivityLifecycleCallbacks {
private boolean inForeground;
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(this);
}
@Override
public void onActivityResumed(Activity activity) {
inForeground = activity instanceof YourActivity;
}
public boolean isInForeground() {
return inForeground;
}
Register App
in AndroidManifest
:
注册App
于AndroidManifest
:
<application
android:name=".App" />
And the final piece of the puzzle:
最后一块拼图:
public class YourReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
App app = (App) context.getApplicationContext();
if(app.isInForeground()){
// do some stuff
}
}
}
回答by surtyaar
You can test if the window has focus- but as stated in dev docs this is not the same as if activity is in foreground.
您可以测试窗口是否具有焦点- 但正如开发文档中所述,这与活动处于前台不同。