如何判断我的Android服务是否在前台运行?

时间:2013-09-10 18:42:22

标签: android

在特定服务的代码中,我想确定服务是否在前台。我看了看:

ActivityManager.RunningServiceInfo

特别是RunningServiceInfo.foreground,但是文档说“如果服务已经要求作为前台进程运行,则设置为true。”

那么我可以依赖RunningServiceInfo.foreground吗?或者还有另一种方式吗?

PS:我没有其他问题,我的服务运行正常。这个问题更多是出于好奇。已经浏览过ASOP并没有看到任何东西,但也许我错过了一些东西......

如果您有类似的问题,这可能有所帮助: How to determine if an Android Service is running in the foreground?

......虽然我发现接受的解决方案不完整。

3 个答案:

答案 0 :(得分:0)

我唯一能想到的是检查服务的流程重要性是否表明它正在运行前台服务或前台活动:

private boolean isForegroundOrForegroundService() {
    //Equivalent of RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE on API 23
    //On prior versions to API 23, maybe the OS just uses 100 as foreground service importance?
    int IMPORTANCE_FOREGROUND_SERVICE = 125;
    return findThisProcess().importance <= IMPORTANCE_FOREGROUND_SERVICE;
}

private ActivityManager.RunningAppProcessInfo findThisProcess() {
    List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses();
    for (ActivityManager.RunningAppProcessInfo proc : runningAppProcesses)
        if (proc.pid == Process.myPid())
            return proc;

    throw new RuntimeException("Couldn't find this process");
}

为此,有一些限制因素:

  • 该服务必须是尝试在前台运行的进程中唯一的服务,否则您将不知道哪个服务导致进程进入前台模式。
  • 必须没有任何活动在同一进程中运行,因为打开活动也会导致进程进入前台模式。
  • 由于与上述相同的原因,除了服务本身之外,其他任何东西都不能使进程进入前台模式。

因此,您可能希望将服务放在自己的专用流程中。不幸的是,这使得您的应用程序结构变得困难,因为多进程应用程序开发比单进程更复杂。

请注意,这主要是理论;我没有测试过这么多或在任何实际应用程序中使用它。如果你采用这种方法,让我知道它是怎么回事。

答案 1 :(得分:-1)

试试这段代码:

private boolean isActivityRunning() {
        List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(1);
        ComponentName runningActivity = tasks.get(0).topActivity;
        return runningActivity.getPackageName().startsWith("com.mypackage");
    }

答案 2 :(得分:-2)

如果我正确理解了您的问题,并且如果我们假设前景意味着您的应用程序有某些活动,那么您可以在应用程序中声明全局静态变量,例如: boolean bIsForeground。 在您的活动中,您可以设置:

@Override
protected void onResume() {
    super.onResume();
    bIsForeground = true;
}


@Override
protected void onPause() {
    super.onResume();
    bIsForeground = false;
}

因此,每当您的活动是前景或“在屏幕上”时,此变量应该为true,这样您的服务就可以知道这是前台活动的。