Context.Startforegroundservice() Did Not Then Call Service.Startforeground()

service crash with Context.startForegroundService() did not then call Service.startForeground()

Android O you can set the background limitation as below;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context!!.startForegroundService(Intent(context, MyService::class.java))
} else {
context!!.startService(Intent(context, MyService::class.java))
}

Android 9 (Pie), Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord

I was waiting my crash report to share the solution. I didn't get any crash or ANR almost 20 days. I want to share my solution. It can help those who encounter this problem.

In onCreate() method

  • First of all, my app is a media application. I didn't implement the mediasession yet. I'm creating a notification channel in the top of onCreate(). Official doc
  • I'm calling Service.startForeground() method after Context.startForegroundService() method. In my prepareAndStartForeground() method.

    Note: I don't know why but ContextCompat.startForegroundService() doesn't work properly.

For this reason, I've added manually same function to my service class instead of calling ContextCompat.startForegroundService()

private fun startForegroundService(intent: Intent) {
if (Build.VERSION.SDK_INT >= 26) {
context.startForegroundService(intent)
} else {
// Pre-O behavior.
context.startService(intent)
}
}

prepareAndStartForeground() method

private fun prepareAndStartForeground() {
try {
val intent = Intent(ctx, MusicService::class.java)
startForegroundService(intent)

val n = mNotificationBuilder.build()
// do sth
startForeground(Define.NOTIFICATION_ID, n)
} catch (e: Exception) {
Log.e(TAG, "startForegroundNotification: " + e.message)
}
}

It's my onCreate()

override fun onCreate() {
super.onCreate()
createNotificationChannel()
prepareAndStartForeground()
}

My onStartCommand()

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (intent == null) {
return START_STICKY_COMPATIBILITY
} else {
//....
//...
}
return START_STICKY
}

onRebind, onBind, onUnbind methods like these

internal var binder: IBinder? = null

override fun onRebind(intent: Intent) {
stopForeground(true) // <- remove notification
}

override fun onBind(intent: Intent): IBinder? {
stopForeground(true) // <- remove notification
return binder
}

override fun onUnbind(intent: Intent): Boolean {
prepareAndStartForeground() // <- show notification again
return true
}

We need to clear something when onDestroy() calling

   override fun onDestroy() {
super.onDestroy()
releaseService()
}

private fun releaseService() {
stopMedia()
stopTimer()
// sth like these
player = null
mContext = null
afChangeListener = null
mAudioBecomingNoisy = null
handler = null
mNotificationBuilder = null
mNotificationManager = null
mInstance = null
}

I hope this solution works properly for you.

Android RemoteServiceExeption: Context.startForegroundService() did not then call Service.startForeground()

So I've almost fixed the problem and no longer get hundreds of crashes every week, but only about one every two days.

Solution is this, when starting the foreground service: Just wait for the main looper in the main thread and then start it. It is much more common, that the 5s until the service needs to be started are enough now.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Handler(Looper.getMainLooper()).post{
MyContext.getContext().startForegroundService(Intent(this, NotificationUtil::class.java))
}
} else {
startService(Intent(this, NotificationUtil::class.java))
}

Context.startForegroundService did not then call Service.startForeground

According to official document of Android 8.0 Background Execution Limits

Android 8.0 introduces the new method
startForegroundService() to start a new service in the foreground.
After the system has created the service, the app has five seconds to
call the service's startForeground() method to show the new service's
user-visible notification. If the app does not call startForeground()
within the time limit, the system stops the service and declares the
app to be ANR.

So, make sure you have started ongoing notification by calling startForeground (int id, Notification notification) in the onCreate() method of your service.

Note: Apps targeting API Build.VERSION_CODES.P or later must request the permission Manifest.permission.FOREGROUND_SERVICE in order to use this API.

Context.startForegroundService() did not then call Service.startForeground() In BroadcastReceiver

Your Service must call startForeground() when it is started, otherwise the system will not allow it to run.



Related Topics



Leave a reply



Submit