question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

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

See original GitHub issue

I am getting firebase report with the following: Galaxy A6+

Fatal Exception: android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{b2dfd2b u0 com.application.service.LocalExoplayerDownloadService}
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2096)
       at android.os.Handler.dispatchMessage(Handler.java:107)
       at android.os.Looper.loop(Looper.java:237)
       at android.app.ActivityThread.main(ActivityThread.java:7860)
       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:1075)

Moto e6

Fatal Exception: android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{1a60cf u0 com.application.service.LocalExoplayerDownloadService}
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1915)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:215)
       at android.app.ActivityThread.main(ActivityThread.java:6939)
       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:870)

Huawai Y5 Lite

Fatal Exception: android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground()
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1956)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:166)
       at android.app.ActivityThread.main(ActivityThread.java:6861)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:450)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
  • ExoPlayer version number: 2.16.1
  • Android version: From Android 8 to Android 11 so far
  • Android device: Samsung Galaxy A6+, Motorola moto e6, HUAWEI Y5 lite

I’m using DownloadService class as specified in the doc https://exoplayer.dev/downloading-media.html and in https://github.com/google/ExoPlayer/blob/release-v2/demos/main/src/main/java/com/google/android/exoplayer2/demo/DemoDownloadService.java

LocalExoplayerDownloadService

private const val JOB_ID = 7654
const val FOREGROUND_NOTIFICATION_ID = 6909
const val DOWNLOAD_NOTIFICATION_CHANNEL_ID = "download_channel"
private const val GROUP_KEY = "com.example.DOWNLOAD_SERVICE"
class LocalExoplayerDownloadService: DownloadService(
    FOREGROUND_NOTIFICATION_ID,
    DEFAULT_FOREGROUND_NOTIFICATION_UPDATE_INTERVAL,
    DOWNLOAD_NOTIFICATION_CHANNEL_ID,
    R.string.exo_download_notification_channel_name, R.string.exo_download_description
) {

    override fun getDownloadManager(): DownloadManager {
        val downloadNotificationHelper: DownloadNotificationHelper = DownloadUtil.getDownloadNotificationHelper(this)
        val downloadManager = DownloadUtil.getDownloadManager()
        downloadManager.addListener(TerminalStateNotificationHelper(this, downloadNotificationHelper)
        return downloadManager
    }

    override fun getScheduler(): PlatformScheduler? {
        return if (Util.SDK_INT >= 21) PlatformScheduler(this, JOB_ID) else null
    }

    override fun getForegroundNotification(
        downloads: MutableList<Download>,
        notMetRequirements: Int
    ): Notification {
       val nManager = NotificationManagerCompat.from(this)
       downloads.filter { it.state == Download.STATE_DOWNLOADING }.forEach {
              val notification = NotificationCompat.Builder(this, DOWNLOAD_NOTIFICATION_CHANNEL_ID)
                   .setSmallIcon(R.drawable.ic_download)
                   .setContentTitle(Util.fromUtf8Bytes(it.request.data))
                   .setProgress(100, it.percentDownloaded.roundToInt(), false)
                   .setOngoing(true)
                   .setGroup(GROUP_KEY)
                   .build()
               nManager.notify(it.request.id.toInt(), notification)
       }
       val title = if(realDownload.isNotEmpty())
            getTranslation(R.string.download_progress, realDownload.size)
        else
            getString(R.string.download_sync)
        return NotificationCompat.Builder(this, DownloadUtil.DOWNLOAD_NOTIFICATION_CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_download)
            .setContentText(getString(R.string.download_current_download))
            .setContentTitle(title)
            .setContentIntent(downloadFragmentIntent)
            .setOngoing(true)
            .setShowWhen(false)
            .setGroup(GROUP_KEY)
            .setGroupSummary(true)
            .build()
}


class TerminalStateNotificationHelper(
    context: Context,
    private val notificationHelper: DownloadNotificationHelper,
) : DownloadManager.Listener {
    private val context: Context = context.applicationContext

    override fun onDownloadChanged(downloadManager: DownloadManager, download: Download, finalException: Exception?) {
        val notification: Notification? = when(download.state) {
            Download.STATE_COMPLETED -> {
                val videoPendingIntent = NavDeepLinkBuilder(context)
                    .setGraph(R.navigation.nav_graph)
                    .setDestination(R.id.videoDetails)
                    .setArguments(
                        VideoDetailsFragmentArgs.Builder(
                            download.request.id,
                            Util.fromUtf8Bytes(download.request.data)
                        ).build().toBundle()
                    )
                    .createPendingIntent()

                notificationHelper.buildDownloadCompletedNotification(
                    context,
                    R.drawable.ic_download,
                    videoPendingIntent, /* contentIntent= */
                    Util.fromUtf8Bytes(download.request.data)
                )
            }
            Download.STATE_FAILED -> {
                val removePendingIntent = PendingIntent.getBroadcast(context, REQUEST_CODE,
                    Intent(context, DownloadReceiver::class.java).apply {
                        action = DownloadService.ACTION_REMOVE_DOWNLOAD
                        putExtra(EXTRA_VIDEO_ID, download.request.id)
                    }, flags)
                notificationHelper.buildDownloadFailedNotification(
                    context,
                    R.drawable.ic_download,
                    removePendingIntent, /* contentIntent= */
                    Util.fromUtf8Bytes(download.request.data)
                )
            }
            else -> { null }
        }
        NotificationUtil.setNotification(context, download.request.id.toInt(), notification)
    }
}

Manifest

<application
....
  <service android:name="com.example.service.LocalExoplayerDownloadService" android:exported="false">
     <!-- This is needed for Scheduler -->
     <intent-filter>
         <action android:name="com.google.android.exoplayer.downloadService.action.RESTART"/>
         <category android:name="android.intent.category.DEFAULT"/>
     </intent-filter>
 </service>
 <service android:name="com.google.android.exoplayer2.scheduler.PlatformScheduler$PlatformSchedulerService"
     android:permission="android.permission.BIND_JOB_SERVICE"
     android:exported="true"/>
 <receiver android:name="com.example.receiver.DownloadReceiver" android:exported="false" />
</application>

In the hope of fixing this issue I even added this recently but I’m still getting crash report

class App: Application() {
       
       fun onCreate() {
              super.onCreate()
              startDownloadServices()
       }

       private fun startDownloadServices() {
        if (Build.VERSION.SDK_INT >= 26) {
            DownloadService.startForeground(this, LocalExoplayerDownloadService::class.java)
        } else {
            DownloadService.start(this, LocalExoplayerDownloadService::class.java)
        }
    }
}

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
ojw28commented, Mar 24, 2022

I don’t think there’s anything actionable for us here. Closing for now, but please let us know if you discover something. We’ll also keep an eye out for other similar issues.

0reactions
yoobicommented, Apr 7, 2022

Just giving some feedback, as said in the initial post I had this code at the startup of my application

class App: Application() {
       
       fun onCreate() {
              super.onCreate()
              startDownloadServices()
       }

       private fun startDownloadServices() {
        if (Build.VERSION.SDK_INT >= 26) {
            DownloadService.startForeground(this, LocalExoplayerDownloadService::class.java)
        } else {
            DownloadService.start(this, LocalExoplayerDownloadService::class.java)
        }
    }
}

after removing startDownloadServices I no longer have crash, it might be related to the 5 seconds delay to show a notification.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Context.startForegroundService() did not then call Service ...
However, the app must call that service's startForeground() method within five seconds after the service is created. Solution: Call ...
Read more >
Context.startForegroundService() Did Not Then Call Service ...
Adding startForeground() command, with notification in the onCreate method. It didn't work. Also, the issue couldn't be reproduced during ...
Read more >
Context.startForegroundService() did not then call Service ...
App doesn't crash. ACTUAL: android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground() -Android build
Read more >
Crash because of the foreground service did not start in time
When playback starts as a result of that. The library will call Context.startForegroundService() and immediately call Service.startForeground() ...
Read more >
Android : Context.startForegroundService() did not then call ...
Android : Context. startForegroundService () did not then call Service. startForeground () [ Beautify Your Computer ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found