Search code examples
androidforeground-serviceandroid-12

Check if app can start foreground service in background on Android 12+


Is there any method to check if my app can start foreground service in background on Android 12 before app actually try to do it and getting ForegroundServiceStartNotAllowedException?

Some method which checks that at least one of the conditions is fulfilled https://developer.android.com/guide/components/foreground-services#background-start-restriction-exemptions

I start my background service as foreground in activity

try {
    context.bindService( // p.s. this context of application, it's bounded to app process instead of activity context
        getServiceIntent(context),
        object : ServiceConnection {
            override fun onServiceConnected(
                className: ComponentName,
                service: IBinder
            ) {
                // service is running in background
                startForegroundService(context)
                // service should be in foreground mode (at least it should be very soon)
                (service as LocalBinder).getService().initialize()
                context.unbindService(this)
                bindServiceInProgress.set(false)
            }

            override fun onServiceDisconnected(arg0: ComponentName) {
                bindServiceInProgress.set(false)
            }
        },
        AppCompatActivity.BIND_AUTO_CREATE
    )
} catch (e: Exception) {
    e.printStackTrace()
    bindServiceInProgress.set(false)
}

but onServiceConnected can fire too late when activity is not visible anymore but I still want to try start the service in foreground mode if it's allowed for this app, so I need some method to check


Solution

  • I guess we can try catch ForegroundServiceStartNotAllowedException

    private fun makeServiceForeground(context: Context): Boolean {
        val intent = getServiceIntent(context)
        return try {
            ContextCompat.startForegroundService(context, intent)
            true
        } catch (e: Exception) {
            e.printStackTrace()
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e is ForegroundServiceStartNotAllowedException) {
                // TODO: notification to disable battery optimization
            }
            false
        }
    }