【问题标题】:How to determine if an Android Service is running in the foreground?如何确定Android Service 是否在前台运行?
【发布时间】:2011-09-21 02:26:24
【问题描述】:

我有一个我认为在前台运行的服务,我如何检查我的实现是否正常工作?

【问题讨论】:

    标签: android service foreground


    【解决方案1】:
    public static boolean isServiceRunningInForeground(Context context, Class<?> serviceClass) {
          ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
          for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
             if (serviceClass.getName().equals(service.service.getClassName())) {
                if (service.foreground) {
                   return true;
                }
    
             }
          }
          return false;
       }
    

    【讨论】:

    • 我发现此答案中的代码比已接受答案中的代码更简洁,并且与已接受的答案不同,即使有超过 50 个服务正在运行,它也能正常工作。
    • 与接受的相同,但更清晰、更短、更简单。还要检查所有服务,不仅仅是 50。
    • 这里唯一的问题是“从 Oreo 开始,此方法不再适用于第三方应用程序。为了向后兼容,它仍将返回调用者自己的服务。”
    • 如果我想在 Android O 中做同样的事情怎么办?
    • getRunningServices 在 Android 9 中已弃用
    【解决方案2】:
    private boolean isServiceRunning(String serviceName){
        boolean serviceRunning = false;
        ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> l = am.getRunningServices(50);
        Iterator<ActivityManager.RunningServiceInfo> i = l.iterator();
        while (i.hasNext()) {
            ActivityManager.RunningServiceInfo runningServiceInfo = i
                    .next();
    
            if(runningServiceInfo.service.getClassName().equals(serviceName)){
                serviceRunning = true;
    
                if(runningServiceInfo.foreground)
                {
                    //service run in foreground
                }
            }
        }
        return serviceRunning;
    }
    

    如果您想知道您的服务是否在前台运行,只需打开其他一些胖应用程序,然后检查服务是否仍在运行或检查标志 service.foreground

    【讨论】:

    • 谢谢,效果很好!我只需要添加这一行: serviceInForeground = runningServiceInfo.foreground;
    • onDestroy() 中的 stopForeground(true) 怎么样?这不会阻止服务在前台运行吗?
    • @user811985 仅供参考,RunningServiceInfo.foreground 上的文档指出:“如果服务已要求作为前台进程运行,则设置为 true。”。也就是说,它不会告诉你 android 是否真的接受了前台服务。 developer.android.com/reference/android/app/…
    • 不幸的是,GetRunningServices 现在被标记为已弃用
    【解决方案3】:

    更有效的答案变体:https://stackoverflow.com/a/36127260/1275265

    public static boolean isServiceRunningInForeground(Context context, Class<?> serviceClass) {
       ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
       for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
          if (serviceClass.getName().equals(service.service.getClassName())) {
             return service.foreground;
          }
       }
       return false;
    }
    

    【讨论】:

      【解决方案4】:

      从 API 26 开始,getRunningService() 已弃用。

      现在的一个解决方案是将您的活动绑定到您的服务。然后您可以从您的 Activity 中调用您的 Service 的方法,以检查它是否正在运行。

      1 - 在您的 Service 中,创建一个扩展 Binder 并返回您的 Service 的类

        public class LocalBinder extends Binder {
              MyService getService() {
                  return MyService.this;
              }
          }
      

      2 - 在您的服务中,声明活页夹

      private final IBinder binder = new LocalBinder();
      

      3 - 在您的 Service 中,实现 onBind(),这将返回 Binder

        @Nullable
          @Override
          public IBinder onBind(Intent intent) {
              return binder;
          }
      

      4 - 在您的服务中,创建一个检查它是否正在运行的方法(例如检查变量是否已初始化)

        public boolean isRunning() {
              // If running
                  return true;
              // If not running
                  return false;
              
          }
      

      5 - 在您的 Activity 中,创建一个保存您的服务的变量

      private MyService myService;
      

      6 - 现在,在您的 Activity 中,您可以绑定到您的服务

      private void checkIfEnabled() {
          ServiceConnection connection = new ServiceConnection() {
      
              @Override
              public void onServiceConnected(ComponentName className,
                                             IBinder service) {
                  MyService.LocalBinder binder = (MyService.LocalBinder) service;
                  myService = binder.getService();
                  
                  // Calling your service public method
                  if(myService.isRunning()) {
                      // Your service is enabled
                  } else {
                      // Your service is disabled
                  }
              }
      
              @Override
              public void onServiceDisconnected(ComponentName arg0) {
      
              }
          };
      
          // Bind to MyService
          Intent intent = new Intent(this, MyService.class);
          bindService(intent, connection, Context.BIND_AUTO_CREATE);
      }
      

      欲了解更多信息,请查看官方文档中的Bound services overview

      【讨论】:

        【解决方案5】:

        这适用于我在 Coinverse 应用程序中获取加密新闻。

        这是最简洁的 Kotlin 解决方案。感谢Abbas Naqdi 在此GitHub issue

        @Suppress("DEPRECATION") // Deprecated for third party Services.
        fun <T> Context.isServiceRunning(service: Class<T>) =
                (getSystemService(ACTIVITY_SERVICE) as ActivityManager)
                    .getRunningServices(Integer.MAX_VALUE)
                    .any { it.service.className == service.name }
        

        【讨论】:

        • 如果您需要停止服务,这是 Android 9.0latest implementation
        • 问题是关于前台运行的服务。所以你也应该检查it.foreground
        【解决方案6】:

        对亚当的回答稍作改动:

        @Suppress("DEPRECATION") // Deprecated for third party Services.
        fun <T> Context.isServiceForegrounded(service: Class<T>) =
            (getSystemService(ACTIVITY_SERVICE) as? ActivityManager)
                ?.getRunningServices(Integer.MAX_VALUE)
                ?.find { it.service.className == service.name }
                ?.foreground == true
        

        【讨论】:

          猜你喜欢
          • 2015-04-02
          • 2010-10-26
          • 2013-09-14
          • 2012-09-10
          • 2019-05-14
          • 1970-01-01
          • 2011-01-15
          • 2016-03-20
          • 2014-06-27
          相关资源
          最近更新 更多