Context.startForegroundService() did not then call Service.startForeground()
Solution 1
From Google's docs on Android 8.0 behavior changes:
The system allows apps to call Context.startForegroundService() even while the app is in the background. However, the app must call that service's startForeground() method within five seconds after the service is created.
Solution:
Call startForeground()
in onCreate()
for the Service
which you use Context.startForegroundService()
See also: Background Execution Limits for Android 8.0 (Oreo)
Solution 2
I called ContextCompat.startForegroundService(this, intent)
to start the service then
In service onCreate
@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= 26) {
String CHANNEL_ID = "my_channel_01";
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("")
.setContentText("").build();
startForeground(1, notification);
}
}
Solution 3
Why this issue is happening is because Android framework can't guarantee your service get started within 5 second but on the other hand framework does have strict limit on foreground notification must be fired within 5 seconds, without checking if framework had tried to start the service.
This is definitely a framework issue, but not all developers facing this issue are doing their best:
startForeground
a notification must be in bothonCreate
andonStartCommand
, because if your service is already created and somehow your activity is trying to start it again,onCreate
won't be called.notification ID must not be 0 otherwise same crash will happen even it's not same reason.
stopSelf
must not be called beforestartForeground
.
With all above 3 this issue can be reduced a bit but still not a fix, the real fix or let's say workaround is to downgrade your target sdk version to 25.
And note that most likely Android P will still carry this issue because Google refuses to even understand what is going on and does not believe this is their fault, read #36 and #56 for more information
Solution 4
I know, too many answers have been published already, however the truth is - startForegroundService can not be fixed at an app level and you should stop using it. That Google recommendation to use Service#startForeground() API within 5 seconds after Context#startForegroundService() was called is not something that an app can always do.
Android runs a lot of processes simultaneously and there is no any guarantee that Looper will call your target service that is supposed to call startForeground() within 5 seconds. If your target service didn't receive the call within 5 seconds, you're out of luck and your users will experience ANR situation. In your stack trace you'll see something like this:
Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{1946947 u0 ...MessageService}
main" prio=5 tid=1 Native
| group="main" sCount=1 dsCount=0 flags=1 obj=0x763e01d8 self=0x7d77814c00
| sysTid=11171 nice=-10 cgrp=default sched=0/0 handle=0x7dfe411560
| state=S schedstat=( 1337466614 103021380 2047 ) utm=106 stm=27 core=0 HZ=100
| stack=0x7fd522f000-0x7fd5231000 stackSize=8MB
| held mutexes=
#00 pc 00000000000712e0 /system/lib64/libc.so (__epoll_pwait+8)
#01 pc 00000000000141c0 /system/lib64/libutils.so (android::Looper::pollInner(int)+144)
#02 pc 000000000001408c /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+60)
#03 pc 000000000012c0d4 /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce(_JNIEnv*, _jobject*, long, int)+44)
at android.os.MessageQueue.nativePollOnce (MessageQueue.java)
at android.os.MessageQueue.next (MessageQueue.java:326)
at android.os.Looper.loop (Looper.java:181)
at android.app.ActivityThread.main (ActivityThread.java:6981)
at java.lang.reflect.Method.invoke (Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1445)
As I understand, Looper has analyzed the queue here, found an "abuser" and simply killed it. The system is happy and healthy now, while developers and users are not, but since Google limits their responsibilities to the system, why should they care about the latter two? Apparently they don't. Could they make it better? Of course, e.g. they could've served "Application is busy" dialog, asking a user to make a decision about waiting or killing the app, but why bother, it's not their responsibility. The main thing is that the system is healthy now.
From my observations, this happens relatively rarely, in my case approximately 1 crash in a month for 1K users. Reproducing it is impossible, and even if it's reproduced, there is nothing you can do to fix it permanently.
There was a good suggestion in this thread to use "bind" instead of "start" and then when service is ready, process onServiceConnected, but again, it means not using startForegroundService calls at all.
I think, the right and honest action from Google side would be to tell everyone that startForegourndServcie has a deficiency and should not be used.
The question still remains: what to use instead? Fortunately for us, there are JobScheduler and JobService now, which are a better alternative for foreground services. It's a better option, because of that:
While a job is running, the system holds a wakelock on behalf of your app. For this reason, you do not need to take any action to guarantee that the device stays awake for the duration of the job.
It means that you don't need to care about handling wakelocks anymore and that's why it's not different from foreground services. From implementation point of view JobScheduler is not your service, it's a system's one, presumably it will handle the queue right, and Google will never terminate its own child :)
Samsung has switched from startForegroundService to JobScheduler and JobService in their Samsung Accessory Protocol (SAP). It's very helpful when devices like smartwatches need to talk to hosts like phones, where the job does need to interact with a user through an app's main thread. Since the jobs are posted by the scheduler to the main thread, it becomes possible. You should remember though that the job is running on the main thread and offload all heavy stuff to other threads and async tasks.
This service executes each incoming job on a Handler running on your application's main thread. This means that you must offload your execution logic to another thread/handler/AsyncTask of your choosing
The only pitfall of switching to JobScheduler/JobService is that you'll need to refactor old code, and it's not fun. I've spent last two days doing just that to use the new Samsung's SAP implementation. I'll watch my crash reports and let you know if see the crashes again. Theoretically it should not happen, but there are always details that we might not be aware of.
UPDATE No more crashes reported by Play Store. It means that JobScheduler/JobService do not have such a problem and switching to this model is the right approach to get rid of startForegroundService issue once and forever. I hope, Google/Android reads it and will eventually comment/advise/provide an official guidance for everyone.
UPDATE 2
For those who use SAP and asking how SAP V2 utilizes JobService explanation is below.
In your custom code you'll need to initialize SAP (it's Kotlin) :
SAAgentV2.requestAgent(App.app?.applicationContext,
MessageJobs::class.java!!.getName(), mAgentCallback)
Now you need to decompile Samsung's code to see what's going on inside. In SAAgentV2 take a look at the requestAgent implementation and the following line:
SAAgentV2.d var3 = new SAAgentV2.d(var0, var1, var2);
where d defined as below
private SAAdapter d;
Go to SAAdapter class now and find onServiceConnectionRequested function that schedules a job using the following call:
SAJobService.scheduleSCJob(SAAdapter.this.d, var11, var14, var3, var12);
SAJobService is just an implementation of Android'd JobService and this is the one that does a job scheduling:
private static void a(Context var0, String var1, String var2, long var3, String var5, SAPeerAgent var6) {
ComponentName var7 = new ComponentName(var0, SAJobService.class);
Builder var10;
(var10 = new Builder(a++, var7)).setOverrideDeadline(3000L);
PersistableBundle var8;
(var8 = new PersistableBundle()).putString("action", var1);
var8.putString("agentImplclass", var2);
var8.putLong("transactionId", var3);
var8.putString("agentId", var5);
if (var6 == null) {
var8.putStringArray("peerAgent", (String[])null);
} else {
List var9;
String[] var11 = new String[(var9 = var6.d()).size()];
var11 = (String[])var9.toArray(var11);
var8.putStringArray("peerAgent", var11);
}
var10.setExtras(var8);
((JobScheduler)var0.getSystemService("jobscheduler")).schedule(var10.build());
}
As you see, the last line here uses Android'd JobScheduler to get this system service and to schedule a job.
In the requestAgent call we've passed mAgentCallback, which is a callback function that will receive control when an important event happens. This is how the callback is defined in my app:
private val mAgentCallback = object : SAAgentV2.RequestAgentCallback {
override fun onAgentAvailable(agent: SAAgentV2) {
mMessageService = agent as? MessageJobs
App.d(Accounts.TAG, "Agent " + agent)
}
override fun onError(errorCode: Int, message: String) {
App.d(Accounts.TAG, "Agent initialization error: $errorCode. ErrorMsg: $message")
}
}
MessageJobs here is a class that I've implemented to process all requests coming from a Samsung smartwatch. It's not the full code, only a skeleton:
class MessageJobs (context:Context) : SAAgentV2(SERVICETAG, context, MessageSocket::class.java) {
public fun release () {
}
override fun onServiceConnectionResponse(p0: SAPeerAgent?, p1: SASocket?, p2: Int) {
super.onServiceConnectionResponse(p0, p1, p2)
App.d(TAG, "conn resp " + p1?.javaClass?.name + p2)
}
override fun onAuthenticationResponse(p0: SAPeerAgent?, p1: SAAuthenticationToken?, p2: Int) {
super.onAuthenticationResponse(p0, p1, p2)
App.d(TAG, "Auth " + p1.toString())
}
override protected fun onServiceConnectionRequested(agent: SAPeerAgent) {
}
}
override fun onFindPeerAgentsResponse(peerAgents: Array<SAPeerAgent>?, result: Int) {
}
override fun onError(peerAgent: SAPeerAgent?, errorMessage: String?, errorCode: Int) {
super.onError(peerAgent, errorMessage, errorCode)
}
override fun onPeerAgentsUpdated(peerAgents: Array<SAPeerAgent>?, result: Int) {
}
}
As you see, MessageJobs requires MessageSocket class as well that you would need to implement and that processes all messages coming from your device.
Bottom line, it's not that simple and it requires some digging to internals and coding, but it works, and most importantly - it doesn't crash.
Solution 5
Your app will crash if you call Context.startForegroundService(...)
and then call Context.stopService(...)
before Service.startForeground(...)
is called.
I have a clear repro here ForegroundServiceAPI26
I have opened a bug on this at : Google issue tracker
Several bugs on this have been opened and closed Won't Fix.
Hopefully mine with clear repro steps will make the cut.
Information provided by google team
Google issue tracker Comment 36
This is not a framework bug; it's intentional. If the app starts a service instance with startForegroundService()
, it must transition that service instance to the foreground state and show the notification. If the service instance is stopped before startForeground()
is called on it, that promise is unfulfilled: this is a bug in the app.
Re #31, publishing a Service that other apps can start directly is fundamentally unsafe. You can mitigate that a bit by treating all start actions of that service as requiring startForeground()
, though obviously that may not be what you had in mind.
Google issue tracker Comment 56
There are a couple of different scenarios that lead to the same outcome here.
The outright semantic issue, that it's simply an error to kick something off with startForegroundService()
but neglect to actually transition it to foreground via startForeground()
, is just that: a semantic issue. That's treated as an app bug, intentionally. Stopping the service before transitioning it to foreground is an app error. That was the crux of the OP, and is why this issue has been marked "working as intended."
However, there are also questions about spurious detection of this problem. That's is being treated as a genuine problem, though it's being tracked separately from this particular bug tracker issue. We aren't deaf to the complaint.
NiceGuy
Updated on July 15, 2022Comments
-
NiceGuy almost 2 years
I am using
Service
Class on the Android O OS.I plan to use the
Service
in the background.The Android documentation states that
If your app targets API level 26 or higher, the system imposes restrictions on using or creating background services unless the app itself is in the foreground. If an app needs to create a foreground service, the app should call
startForegroundService()
.If you use
startForegroundService()
, theService
throws the following error.Context.startForegroundService() did not then call Service.startForeground()
What's wrong with this?
-
Kimi Chiu over 6 yearsI did this in the
onStartCommand
method, but I'm still getting this error. I calledstartForegroundService(intent)
in myMainActivity
. Maybe the service is started too slow. I think the five seconds limit should not exist before they can promise the service is started immediately. -
Kimi Chiu over 6 yearsMe too. But I'm still getting this error occasionally. Maybe the Android can't guarantee it will call the
onCreate
in 5 seconds. So they should redesign it before they force us follow the rules. -
Tyler over 6 yearsI was calling startForeground in onStartCommand(), and I was occasionally getting this error. I moved it to onCreate and I haven't seen it since (crossing fingers).
-
Artist404 over 6 yearsThis creates a local notification in Oreo saying "APP_NAME is running. Tap to close or see info". How to stop showing that notification?
-
humazed over 6 yearsyou can't if you want to run Foreground service this is a new restriction introduced in android o.
-
Artist404 over 6 years@KimiChiu was doing exactly same but still it was crashing, but only while i was in the foreground so I put a check on the ContextCompat.startForegroundService(this, intent) , if app is in foreground do ContextCompat.startService(this, intent), but if it is in background then only do ContextCompat.startForegroundService(this, intent). Check if it helps
-
Kimi Chiu over 6 yearsNo, the Android Team claimed this is an intended behavior. So I just redesigned my app. This is ridiculous. Always need to redesign apps due to these "intended behavior". It's the third time.
-
Kimi Chiu over 6 yearsThe main cause of this problem is the service was stopped before it was promoted to the foreground. But the assertion didn't stop after the service get destroyed. You can try to reproduce this by adding
StopService
after callingstartForegroundService
. -
southerton about 6 years5 seconds period is definitely not enough, this exception happens very often in debug sessions. I suspect it also WOULD happen in release mode from time to time. And being FATAL EXCEPTION it just crashes the app! I tried to catch it with Thread.setDefaultUncaughtExceptionHandler(), but even on getting it there and ignoring android freezes the application. That's becuase this exception is triggered from handleMessage(), and main loop effectively ends... looking for workaround.
-
Amrut about 6 yearsDo we need to make these changes in case of JobIntentService? Or it is handling it internally?
-
humazed about 6 yearsno, the job classes are created to handle the background work in android Oreo. so you don't need to show notification.
-
Alex about 6 yearsDid you tried it in some app that has at least several thousands users? I tried, some users still have the crash issues.
-
Ahmad Arslan about 6 yearsNo no I am using the exact code and I don't see the clients getting crash.
-
Alex about 6 yearsHow much users u have? I seen ~10-30+ crashes daily (with the error) in app that had 10k users per day. Of course, it happens only for users with android 8.0 and android 8.1, in case targetSdkVersion is 27. All the problems disappear to 0 crashes right after I set targetSdkVersion to 25.
-
Ahmad Arslan about 6 yearsonly 2200 user :-/ but did not get any crash
-
southerton about 6 yearsI was getting this exception quite often in debug mode, finally decided to catch the exception with custom exception handler and keep the app running. choruscode.blogspot.com/2018/05/…
-
Ahmad Arslan almost 6 years@Alex strange I am getting the ANR on nexus and HTC devices :( do you have any solution ?
-
Jeeva almost 6 years@Alex how did you fix this issue??
-
Ahmad Arslan almost 6 yearsI was using intent service right inside of this foreground service which creates error and sometimes crashes, I have removed it and worked perfectly well
-
Alex almost 6 years@Jeeva, not really. Atm, I use targetSdkVersion 25 with compileSdkVersion 27. It looks likes the best way after lot of experiments.... Hope they will finish developer.android.com/topic/libraries/architecture/… before August 2018 because android-developers.googleblog.com/2017/12/…
-
Jeeva almost 6 years@Alex Thanks mate let me know if you have any better solutions
-
swooby almost 6 yearsBest update I have seen is issuetracker.google.com/issues/76112072#comment56. I rewrote my code to use Context.bindService which completely avoids the problematic call to Context.startForegroundService. You can see my sample code at github.com/paulpv/ForegroundServiceAPI26/tree/bound/app/src/…
-
Anand Savjani almost 6 yearsI called Context.startForegroundService() method in broadcast receiver. so how to handle in this situation? because onCreate() is not available in broadcast receiver
-
rcell almost 6 yearsWhy both onCreate and onStartCommand? Can you just put it in onStartCommand?
-
Vasily Kabunov over 5 yearsDon't forget to add
setSmallIcon
method to the chain of builder methods, otherwise the default notification "App is running" will be shown -
Marlon over 5 yearsDon't use higher numbers for the notification ID also. Try to use one digit IDs. stackoverflow.com/a/12228555/2527204
-
Amin Pinjari over 5 yearsIn my case I was using ID 1, thanks, issue got resolved
-
makovkastar over 5 yearsYou should call it instead of context.stopService(serviceIntent) when you want to stop the service.
-
CopsOnRoad over 5 yearsI am using ID 101, still I receive this error sometimes.
-
M. Usman Khan over 5 yearsIf I call startForeground in onCreate(), then even startService() will start it in foreground. what's the purpose of startForegroundService()?
-
Frank over 5 yearsstopSelf must not be called before startForeground => or directly after, because it seems to cancel the "startForeground" when you do.
-
Gerry about 5 yearsFATAL EXCEPTION: main android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel=null pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x40 color=0x00000000 vis=PRIVATE) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1821) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6626)
-
Andris about 5 yearsShould be Util.SDK_INT >= 26, not just bigger
-
android developer about 5 years@southerton I think you should call it on
onStartCommand()
instead ofonCreate
, because if you close the service and start it again, it might go toonStartCommand()
without callingonCreate
... -
Prags about 5 yearsWe can check response from google team here issuetracker.google.com/issues/76112072#comment56
-
Lxu almost 5 yearsI executed some tests, and even if onCreate is not called if the service is already created, you don't need to call startForeground again. Hence you could call it only on the onCreate method and not in the onStartCommand. Probably they consider the single instance of service as being in foreground after the first call till its end.
-
matdev almost 5 yearsThis causes a crash "Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification". Also, Notification.Builder is deprecated as of API 26
-
user3135923 almost 5 yearsif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { stopForeground(true); } else { stopForeground(true); } what is this if else for? both case you were doing the same, stopForeground(true);
-
DarShan almost 5 yearsno need for version check manually, simply use
ContextCompat.startForegroundService()
, it will do that for you. -
Justin Stanley almost 5 yearsI believe you meant to put stopSelf(); inside of the else block instead of stopForeground(true);
-
sandy almost 5 yearsYes, @JustinStanley use stopSelf();
-
CopsOnRoad over 4 yearsGood answer but there is a major issue,
JobIntentService
runs immediately as anIntentService
below Oreo, but schedules a Job on and above Oreo, soJobIntentService
doesn't start immediately. More info -
Oleg Gryb over 4 years@CopsOnRoad Service doesn't start immediately when you call startFregroundService either. It starts when Mr. Looper decides to start it, which is obvious from the stack trace, and that's actually the root cause of the problem.
-
CopsOnRoad over 4 yearsYou're right foreground service may not start within 5 seconds of the time limit (and Google is the one to be blamed for this), but
JobService
is for like 15 mins interval stuff, I upvoted your post because the approach is good but not useful. -
Oleg Gryb over 4 years@CopsOnRoad It's very useful and it starts immediately in my case, As I wrote, it is used for real time interactions between phone and a smartwatch. No way, a user would wait 15 minutes to send data between these two. Works very well and never crashes.
-
CopsOnRoad over 4 yearsSounds cool, would make your answer much worth if you can share some sample code, I am new to Android, and found that
Job...
takes time to start and it is advance version ofAlarmManager
. -
Oleg Gryb over 4 yearsProbably I will when time permits: I'll need to de-couple it from custom-specific code and de-compile some proprietary Samsung libs
-
CopsOnRoad over 4 yearsNo worries, take your time. Good day!
-
Aba over 4 yearsShouldn't
startForeground
be called inonCreate
? -
Prajwal Waingankar over 4 yearsI m using NotificationManager and not Notification class. How can i implement this?
-
mr5 over 4 yearsI'm using 0 as the notification ID of the initial call for
startForeground
. Changing it to 1 fixes the issue for me (hopefully) -
Emil over 4 yearshey, i just voted your comment up because i am exactly looking for SAP for samsung. Do you have any code sample or github repo where i can see your implementation.
-
Oleg Gryb over 4 years@batmaci I used examples provided by Samsung in AccessorySDK_v2.6.1.zip. Go to Samples(Web), find HelloMessage, Provider(Android)_Consumer(Tizen) and see ProviderActiviy.java and ProviderService.java. I had to convert them to Kotlin in my case.
-
Emil over 4 years@OlegGryb when you use JobService, does it work independent than provider android app. Currently with Foreground service, I am updating Provider app on real time using Consumer watch app. Are you able to do this? FitnesPall app has interesting implementation. When you start watch app, it automatically initializes fitnesspall service on your android phone. I guess that they use job instead of foregroundservice
-
Oleg Gryb over 4 years@batmaci - JobService is used by SAP internally. See Update 2 in OP for details.
-
Emil over 4 yearsquick quesiton: SAAgentV2.requestAgent - where do you call this? within mainactivity oncreate? using SAAgent it wasnt required as it it was registered automatically.
-
Emil over 4 years@OlegGryb i achieved connection using SAAgentV2 and tested it yesterday for an hour between my watch and phone. it is fluent. Amazing how awesome is the connection without dropping. thank you for your help. I did it using xamarin.android and with c# was bit trickier from java and kotlin ;) now have to check in older android versions if it works also.
-
Oleg Gryb about 4 yearsyes, as I wrote, bind should work, but I've switched already to JobServive and am not going to change anything unless this one gets broken too ':)
-
IgorGanapolsky about 4 yearsSo what is the solution?
-
Mateen Chaudhry about 4 yearsin some Xiaomi devices activities can't be started from the background
-
Mateen Chaudhry about 4 yearsyou are starting your service from background or in activity?
-
a54studio about 4 yearsBackground. The problem is that Android can't guarantee the service will start in the allotted time. One would think they would just throw an error to ignore it if you want, but alas, not Android. It has to be fatal. This helped in our app, but didn't fix it totally.
-
a54studio about 4 yearsThis actually just kicks the service to startService rather than startForegroundService if null. The if statement would have to be nested, otherwise the app would crash trying to use services on a later version at some point.
-
Dmytro Rostopira almost 4 yearsBut, according to docs, stopForeground
...does not stop the service from running (for that you use stopSelf() or related methods)
-
Roy Solberg almost 4 years@DimaRostopira Yes, in practice I see the system taking care of stopping the service from running after being inactive for a while (maybe a minute). It isn't ideal, but it stops the system from complaining.
-
Atif Waqar over 3 yearsThat was a quick solution. Thanks ^^
-
fsljfke over 3 yearsI think the first comment about it not running immediately is right. I am experiencing this. I am using a widget button to start a JobIntentService.
-
gregko over 3 yearsThank you, just implemented your solution in an app with well over 5M installs, let's see. Hope for the best.
-
JohnnyLambada over 3 yearsMy app has this permission yet is still experiencing the issue described in the question.
-
Shrdi over 3 years@JohnnyLambada it seems only an activity can startForgroundService, try to startService in background instead.
-
gregko over 3 yearsIt works for me so far - almost a month later and no more crashes or ANRs related to startForegroundService() - Thanks!
-
user924 over 3 yearsyou don't need to create a service to stop it, just use local broadcast manager ))
-
Gaurav Singla over 3 yearsIts not a different Service. Its the same service which I want to stop!
-
user924 over 3 yearsI didn't say anything about different service, I mean why are you trying to stop while it's being started?
-
user924 over 3 yearsuse broadcast locale messages
-
Gaurav Singla over 3 yearsDear user924, If I have to stop the service, There is no need to BroadCast too, I can call context.stopService() directly. Above answer is a trick to solve the issue happening on Samsung devices in case you stop the service just before its onStartCommand is actually called.
-
Malachiasz over 3 yearsI have been calling startForeground() in both onCreate() and onStartCommand() and I have no issues. Before when I had in one of them there were some crashes.
-
Malachiasz over 3 yearsI had also the issue that foreground notification was not removed, when my service was very short running. Adding 100ms delay before the call to stopForeground(true); stopSelf(); has helped. Your solution did not help. (Pixel 3, Android 11)
-
Duna over 3 yearsI have an app that has 30k active users on Play Store. And I have the same issue: ~30 daily crashes on Android 8+ because of 5 sec time limit to start foreground. Crashes comes from various devices, even this year phones releases(S20Ultra, Motorola...)The Android design does not guarantee the call will be triggered within 5 sec and the service get killed by the OS. Google has a long list of feedback regarding this issue but they do not admit this is design flaw. They should redesign it better before for force us to drop background services.
-
user924 over 3 years@OlegGryb Does
JobService
work all the time?. For example will it work for background video recording with screen turned of for 24 hours? -
user924 over 3 yearsSo this is wrong to call
JobService
as good replacement, cause it can't run all the time, only sticky foreground service can do it -
MikkelT about 3 yearsTried this on my app (200k MAU) and still get this error. Mostly Samsung it seems for some reason (maybe statistical, but idk).
-
thirtyyuan about 3 yearsSome phone like VIVO, you will still crash even if you are call stopService() after startForeground(), on Android 8.1. see: my logcat
-
lasec0203 about 3 years@swooby your solution helped me greatly.
-
user924 about 3 yearsthe question is too old for Android 12
-
user924 about 3 yearswhy do make it foreground only for Oreo, nonsense
-
user924 about 3 yearsa tricky solution, I will try it, have 80k active users in my app
-
user924 about 3 years
because if your service is already created and somehow your activity is trying to start it again, onCreate won't be called.
- if service was started before then this service is already in foreground because it becomes foreground inonCreate
, so this sentence doesn't make any sense... -
user924 about 3 yearswhat an offtopic question. it's not about oreo, it still will crash from time to time, just test it with app which has at least 30K users
-
user924 about 3 yearsyou are so smart!!! we all do it... but boy your users will still face crash from time to time
-
user924 about 3 yearsin my case it's not possible because I don't use
context.stopService
. I send local broadcast from activity to stop service, service registers to this broadcast, callsstopSelf
, so it stops itself, when it callsstopSelf
,startForeground
was called before 100% -
user924 about 3 yearsbut you have to unbind service in onStop of activity cycle
-
user924 about 3 years` // This is the key: Without waiting Android Framework to call this method // inside Service.onCreate(), immediately call here to post the notification.` - I'm not sure about this, how can you start notification before
onCreate
of Service was called. And whenonServiceConnected
was called, then it meansonCreate
was already called, so there is quite nonsense in your sentence -
user924 about 3 years
myService.startForeground(myNotificationId, MyService.getNotification());
you can move it toonCreate
, becauseonServiceConnected
is called afteronCreate
!!! -
user924 about 3 yearsthis is still didn't help, I have 80K active users (200K downloads)
-
user924 about 3 yearsthis is still didn't help, I have 80K active users (200K downloads)
-
Hexise about 3 years@user924 As I mentioned, it can reduce at least 95% of this kind of crash, but still cannot 100% avoid this problem. I did not find a way to solve this exception 100%. Sorry.
-
CopsOnRoad almost 3 years@RavindraKushwaha Not really.
-
Malachiasz over 2 yearsHow is this a solution if Context.startForeground() is necessary to start a service from the app's in background state?
-
zelig74 over 2 yearsAlthough this solution is recommended by @CommonsWare in his comment stackoverflow.com/questions/55894636/…, it doesn't work perfectly. After calling startForeground() unbindService(), the service is sometimes destroyed by system, and immediately started again. When the service initializes a worker thread during startup, we get an Error java.lang.InternalError: Thread starting during runtime shutdown :-(
-
Beloo over 2 years@user924 Your comments to this topic are quite reasonable. Have you found a solution? I'm also struggling to find one. Looks like the best option we can do is to ensure that
startForegroundService
is called when an app is not overloaded. For example calling it on an app initialization should be avoided. -
DIRTY DAVE over 2 yearsI had wasted so much time figuring out why it was crashing and not understanding why. The issue was the notification ID for
startForeground()
. Change it to something other than 0. -
Vicente Domingos over 2 yearsIf you are testing on your AVD, remove the code: startService(serviceIntent). Well, AVD will always try to run this code - but it will find a version greater than 26.
-
Hzzkygcs over 2 years
I'm using 0 as the notification ID of the initial call for startForeground. Changing it to 1 fixes the issue for me (hopefully)
This solution resolved my problem too. Has anyone figured out why it is the way it is? -
ManxJason over 2 yearsFixed it for us, thanks.
-
Martin Zeitler about 2 yearsRandomizing the
NOTIFICATION_ID
is quite problematic - a public static constant would be better, because one needs it to update theNotification
later on ...anything but0
works. -
Emil almost 2 yearsonCreate is called before onStartCommand i thought. are you not doing otherway around here?
-
Emil almost 2 yearsdo you mean that startService will still work for all SDK versions?
-
Gaurav Singla almost 2 years@Emil You are right. Idea to let the onCreate complete and stop the service from onStartCommand. So that OS thinks onCreate was called, Notification was shown, finally stopped and won't throw the exception.
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Kunal Kalwar almost 2 yearsGuys see my answer its working for me stackoverflow.com/a/72754189/12228079
-
Dan Alboteanu almost 2 yearsthis is what I needed inside Manifest to be able to continue Play Audio <service android:name=".common.audio.AudioPlayerService" android:foregroundServiceType="mediaPlayback" ....