How to determine if an Android Service is running in the foreground?

后端 未结 6 902
眼角桃花
眼角桃花 2020-11-29 04:31

I have a service which I believe to have running in the foreground, How do I check if my implementation is working?

相关标签:
6条回答
  • 2020-11-29 05:04
    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;
       }
    
    0 讨论(0)
  • 2020-11-29 05:09

    A more efficient variation of answer: 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;
    }
    
    0 讨论(0)
  • 2020-11-29 05:12

    As of API 26, getRunningService() is deprecated.

    One solution now is to bind your Activity to your Service. Then you can call a method of your Service from your Activity, to check if it is running.

    1 - In your Service, create a class that extends Binder and returns your Service

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

    2 - In your Service, declare the binder

    private final IBinder binder = new LocalBinder();
    

    3 - In your Service, implement onBind(), which will return the Binder

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

    4 - In your Service, create a method that check if it is running (for example check if variables are initialized)

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

    5 - In your Activity, create a variable that holds your Service

    private MyService myService;
    

    6 - Now, in your Activity, you can bind to your Service

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

    For more info, check Bound services overview from official documentation.

    0 讨论(0)
  • 2020-11-29 05:19
    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;
    }
    

    If you want to know if your service is running in foreground just open some others fat applications and then check if service is still running or just check flag service.foreground.

    0 讨论(0)
  • 2020-11-29 05:22

    This worked for me in the Coinverse app for crypto news.

    It's is the most concise Kotlin solution. Thanks to Abbas Naqdi in this 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 }
    
    0 讨论(0)
  • 2020-11-29 05:27

    Little touch on Adam's answer:

    @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
    
    0 讨论(0)
提交回复
热议问题