【问题标题】:How can I tell if my Android service is running in the foreground?如何判断我的 Android 服务是否在前台运行?
【发布时间】:2013-09-14 14:43:58
【问题描述】:

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

ActivityManager.RunningServiceInfo

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

那么我可以依赖 RunningServiceInfo.foreground 吗?还是有别的办法?

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

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

...虽然我发现公认的解决方案不完整。

【问题讨论】:

  • 你想通过查看服务是否在前台运行来完成什么?
  • 我在调用 setForeground 时遇到了问题,但服务在负载下仍然被杀死。原来我没有正确调用 setForeground(传递它 id=0)。但在我意识到我实际上并不知道该服务在前台之前,只是我请求了它。所以我寻找了一种方法来确定该服务是否被前台处理并且找不到。所以我想我会把它摆给 SO ...
  • 好吧,它不是 setForeground 而是 startForeground(),使用它你需要创建一个显示在通知栏中的通知
  • 对不起,你是对的,我的意思是 startForeground() 不是 setForeground()。是的,我知道这需要通知,谢谢。

标签: android


【解决方案1】:

试试这个代码:

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

【讨论】:

    【解决方案2】:

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

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

    为此,有一些限制:

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

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

    请注意,这主要是理论;我还没有测试过这么多,也没有在任何实际应用程序中使用过它。如果您采用这种方法,请告诉我情况如何。

    【讨论】:

      【解决方案3】:

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

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

      因此,每次您的活动在前台或“屏幕上”时,此变量都应该为真,这样您的服务就可以知道前台处于活动状态。

      【讨论】:

        猜你喜欢
        • 2010-10-19
        • 2011-09-15
        • 2021-10-15
        • 1970-01-01
        • 1970-01-01
        • 2012-01-07
        • 2021-02-23
        • 2019-01-25
        • 2019-05-14
        相关资源
        最近更新 更多