37

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

user811985
  • 503
  • 1
  • 5
  • 10

7 Answers7

41
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;
   }
georgeok
  • 5,321
  • 2
  • 39
  • 61
32
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.

Cœur
  • 37,241
  • 25
  • 195
  • 267
piotrpo
  • 12,398
  • 7
  • 42
  • 58
  • 5
    Thanks that worked great! I just needed to added this line: serviceInForeground = runningServiceInfo.foreground; – user811985 Jun 23 '11 at 11:25
  • What about stopForeground(true) in onDestroy()? Wouldn't that stop the service from running in the foreground? – IgorGanapolsky Oct 26 '12 at 02:05
  • 4
    @user811985 FYI, the documentation on RunningServiceInfo.foreground states: "Set to true if the service *has asked* to run as a foreground process.". That is, it doesn't tell you if android has actually accepted a service in to the foreground. http://developer.android.com/reference/android/app/ActivityManager.RunningServiceInfo.html#foreground – newbyca Sep 10 '13 at 18:25
  • 2
    Unfortunately, GetRunningServices is now marked as depreciated – MBentley Jul 09 '19 at 14:02
13

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;
}
Mark
  • 7,446
  • 5
  • 55
  • 75
6

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.

VRZ78
  • 171
  • 1
  • 3
  • Hi, Could you please share logic inside isRunning function, how to check service is running after one hour app is in background and succeeding opening of the application – Anoop Mar 25 '22 at 02:18
  • 1
    What if the activity/app process cleared? – Zain May 30 '22 at 09:29
3

Starting with API29 (Q), you can simply check it with the following code.

Can be called from inside your service. If you don't have your service instance, you can obtain it by using binder.

class MyService : Service {
    val isForeground: Boolean get() = foregroundServiceType != FOREGROUND_SERVICE_TYPE_NONE
}
Peter
  • 340
  • 4
  • 13
  • 1
    Note that the type is ```FOREGROUND_SERVICE_TYPE_NONE``` only until it has been started once. Calling ```stopForeground()```, whether or not you remove the notification, will still result in ```foregroundServiceType``` not being ```FOREGROUND_SERVICE_TYPE_NONE```. I would recommend incorporating one of the ```getRunningService()``` answers (and check the ```foreground``` field), even though it's deprecated. – technicalflaw Sep 23 '22 at 11:02
  • @technicalflaw thanks for pointing this out. I'm actually not sure if this a bug or poorly written documentation. I've made an [issue](https://issuetracker.google.com/issues/261149524) on google tracker. – Peter Dec 02 '22 at 14:52
1

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
Rez
  • 4,501
  • 1
  • 30
  • 27
0

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 }
AdamHurwitz
  • 9,758
  • 10
  • 72
  • 134
  • If you need to stop a service this is the [latest implementation](https://stackoverflow.com/a/55208488/2253682) for **Android 9.0**. – AdamHurwitz Jun 07 '19 at 20:05
  • 2
    The question is about the service running in the foreground. So you should also check for `it.foreground`. – Elyess Abouda Jul 04 '19 at 08:38