59

我已经实现了一个由 AlarmManager 触发的 BroadcastReceiver。AlarmManager 在 BOOT_COMPLETED 上初始化。所以我必须在清单中声明接收者。

我的问题是我希望 BroadcastReceiver 只在我自己的活动都没有在前台时(也就是用户没有与我的应用程序交互)时做某事。我从远程服务器中提取信息,并且无论如何都不想通知用户他当前是否在我的应用程序中。

到目前为止,我还没有设法确定我的应用程序是否在前台。有没有办法做这样的事情?ActivityManager 告诉我我的应用程序是否正在运行,但不告诉我它是否在前台。

这个问题和这里描述的差不多:Inform Activity from a BroadcastReceiver ONLY if it is in the frontground

解决方案:

在评估了几个解决方案之后,我想快速概述一下我认为处理后台/前台活动的最佳方法。

首选方法是在活动的 onResume 方法中注册广播接收器,并在 onPause 上的活动中取消注册。任何服务或其他背景元素都需要发送带有特定操作的广播意图,您的活动将拦截该操作。

如果您的活动在前台,它将注册其意图接收器,并且能够直接处理从您的服务发送的意图。如果它不在前台,它将不会收到意图,但调用广播的服务将知道没有人拦截其广播意图,并且能够自行处理。例如,它可以启动所需的活动、显示通知等。

4

7 回答 7

27

以下答案:“应用程序是否在后台运行”,总结了可用于后台/前台检查的解决方案。

注意:
以前此答案建议使用ActivityManager.getRunningAppProcesses(),但是该方法似乎并不完全可靠,不鼓励使用。查看上面的链接了解详细信息。

于 2011-03-07T15:14:05.297 回答
12

您的活动可以跟踪自己的状态,以确定它是否在前台(将布尔值设置为truein onStart(),to falsein onStop())。唉,该布尔值不会自动提供给您Activity

于 2010-02-23T00:09:29.860 回答
4

ActivityManager#getRunningAppProcesses()返回一个列表RunningAppProcessInfo。每个RunningAppProcessInfo都有一个称为重要性的字段。重要性等于RunningAppProcessInfo.IMPORTANCE_FOREGROUND似乎表明用户正在积极观察哪些活动。还有RunningAppProcessInfo.IMPORTANCE_VISIBLE一个较低但可能值得一试。

于 2010-02-23T01:45:45.907 回答
3

我已经实现了一个由 AlarmManager 触发的 BroadcastReceiver。AlarmManager 在 BOOT_COMPLETED 上初始化。所以我必须在清单中声明接收者。

我的问题是我希望 BroadcastReceiver 只在我自己的活动都没有在前台时(也就是用户没有与我的应用程序交互)时做某事。我从远程服务器中提取信息,并且无论如何都不想通知用户他当前是否在我的应用程序中。

到目前为止,我还没有设法确定我的应用程序是否在前台。有没有办法做这样的事情?ActivityManager 告诉我我的应用程序是否正在运行,但不告诉我它是否在前台。

似乎没有直接的方法来确定您的活动之一是否是当前正在运行的前台活动。但是,您可以通过使用有序广播和两个广播接收器来获得所需的效果。一个广播接收器需要在 OnResume() 中注册并在 OnPause() 中取消注册。正如您已经完成的那样,第二个广播接收器将在您的清单中声明。为您的接收器设置 android:priority ,这样如果动态注册的接收器已注册,它将首先接收意图,然后您可以吃掉意图,这样您在清单中注册的广播接收器就不会收到通知。

于 2011-08-14T20:56:17.870 回答
3

查看我的解决方案以确定活动是否在前台: http: //www.mannaz.at/codebase/android-activity-foreground-surveillance/

将逻辑从“在前台”恢复为“不在前台”应该很容易。

于 2011-01-26T20:25:48.970 回答
1

我会使用ActivityLifecycleCallbacks来获得更清洁的解决方案。

可能是不安全的,在您决定在生产中使用下面的示例之前阅读此内容。它适用于我的设备和操作系统版本的“家庭开发”。

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;
}

注册:App_AndroidManifest

<application
        android:name=".App" />

最后一块拼图:

public class YourReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        App app = (App) context.getApplicationContext();
        if(app.isInForeground()){
            // do some stuff
        }
    }
}
于 2014-12-05T16:28:27.403 回答
1

您可以测试窗口是否具有焦点- 但正如开发文档中所述,这与活动是否在前台不同。

于 2011-02-14T15:55:36.947 回答