Due to limitations of Android O we can't start services from background anymore, also it's not possible to register Implicit BroadcastReceiver in the manifest, so we have to do it in code :
Context.registerReceiver()
Despite the fact that the topic is no longer new, I still don't know the reliable way to know if application is in Foreground or Background. I have seen some solutions like :
- make a variable and switch it in Activity's onStart(), onStop()
- I have also seen ActivityManager used for this purpose, but this is deprecated solution
So, is there any way to know for sure in what state our application right now? I'm asking this because recently I have encountered a strange bug on some devices, I can't start a service, here is the stack:
java.lang.RuntimeException: Error receiving broadcast Intent { act=android.net.conn.CONNECTIVITY_CHANGE flg=0x4000010 (has extras) } in com.vc.receivers.RunTimeReceiver@299a843
at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$-android_app_LoadedApk$ReceiverDispatcher$Args_54441(LoadedApk.java:1369)
at android.app.-$Lambda$aS31cHIhRx41653CMnd4gZqshIQ.$m$7(Unknown Source:4)
at android.app.-$Lambda$aS31cHIhRx41653CMnd4gZqshIQ.run(Unknown Source:39)
at android.os.Handler.handleCallback(Handler.java:795)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:6861)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:450)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
Caused by: java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.trueconf.videochat/com.vc.service.AppNotificationService }: app is in background uid UidRecord{621583 u0a323 CEM idle change:cached procs:1 seq(0,0,0)}
at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1525)
at android.app.ContextImpl.startService(ContextImpl.java:1481)
at android.content.ContextWrapper.startService(ContextWrapper.java:650)
at com.vc.data.NotificationsStorage.updateAppStateNotify(NotificationsStorage.java:285)
at com.vc.model.NetworkStateHandler.getNetworkTypeForUsage(NetworkStateHandler.java:292)
at com.vc.model.NetworkStateHandler.performRefreshConnectionInfo(NetworkStateHandler.java:137)
at com.vc.model.NetworkStateHandler.refreshConnectionInfo(NetworkStateHandler.java:104)
at com.vc.receivers.RunTimeReceiver.onReceive(RunTimeReceiver.java:54)
at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$-android_app_LoadedApk$ReceiverDispatcher$Args_54441(LoadedApk.java:1356)
... 9 more
I register BroadcastReceiver after Application's onCreate() method, then it will immediately receive CONNECTIVITY_CHANGE Intent and start a service. I've thought that app state is Foreground after Application's onCreate() is called but apperently it's not.