6

This is a similar question to How to check if a service is running on Android? but since the question is old and the answers provided there are deprecated or not working properly. Thus the separate question.

I have an implementation, that fires a Service on Boot Complete, but I also want to start the service in onCreate of MainActivity, in case the service was not started before.

here are what I have tried:

1. Fetch Static Boolean to get the state of the Service as demonstrated below.

MyService.kt

class MyService : Service() {
    override fun onCreate() {
        super.onCreate()
        isServiceStarted = true
    }
    override fun onDestroy() {
        super.onDestroy()
        isServiceStarted = false
    }
    companion object {
        var isServiceStarted = false
    }
}

MainActivity.kt

class MainActivity : AppCompatActivity(){
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val serviceStarted = MyService.isServiceStarted
        if (!serviceStarted) {
            val startMyService = Intent(this, MyService::class.java)
            ContextCompat.startForegroundService(this, startMyService)
        }
    }
}

but I soon discovered that onDestroy is not always called when a Service is destroyed, thereby leaving my static boolean variable (isServiceStarted) to be true, when in reality it has been destroyed.

2.A function to check

fun isMyServiceRunning(serviceClass : Class<*> ) : Boolean{
    var manager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    for (service in manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.name.equals(service.service.className)) {
            return true
        }
    }
    return false
}

The Call

isMyServiceRunning(MyService::class.java)

Problems with this approach include: - getRunningServices is deprecated since Android O (API 27), - It is resource consuming and inefficient to loop through running services like that and because the docs say:

Note: this method is only intended for debugging or implementing service management type user interfaces.

It's not meant for control flow!

What is an Elegant/Efficient way to check if a Service is already running?

saeed foroughi
  • 1,662
  • 1
  • 13
  • 25
EdgeDev
  • 2,376
  • 2
  • 20
  • 37
  • You can try to bind to your service **without** [`BIND_AUTO_CREATE`](https://developer.android.com/reference/android/content/Context.html#BIND_AUTO_CREATE) flag, but it's a bit more tricky because result will be not receiving `onServiceConnected` callback instead of direct boolean. – Pawel Feb 10 '19 at 13:29
  • 1
    I would use method 1. The only time `onDestroy()` is not called is if your app is terminated. And when the app starts up again, `isServiceStarted` will be false, just like it is every time the app starts. If you disagree, please provide more information. – greeble31 Feb 10 '19 at 16:03
  • @greeble31 that's the current implementation – EdgeDev Feb 10 '19 at 17:04

1 Answers1

0

If service is in the application process just use the static field inside service (companion object) or bind to service. If the service runs in remote process use Messanger if you want to have a synchronized communication or AIDL when you want to care about threads.

LukaszTaraszka
  • 801
  • 1
  • 10
  • 26