Search code examples
androidkotlinandroid-workmanager

Playing an audio file in the background with WorkManager


I am trying to set up an Android app with Kotlin. It should be able to play an audio file in the background. For that I use WorkManager.

There is a button in the main activity to fire up the play of the audio file.

At this point I have something partly working. If I fire the audio playing by tapping the button it plays as expected when the app stays in the foreground. But when the app goes to the background it only keeps playing for about seven seconds and then stops instead of waiting for the end of the audio file as I expect.

Here is the audio/play button OnClickListener:

playBtn.setOnClickListener {
    val playWorkRequest = OneTimeWorkRequestBuilder<AudioWorker>().build()
    val wrkMgr = WorkManager.getInstance(applicationContext)
    wrkMgr.enqueue(playWorkRequest)
    val wrkInfo = wrkMgr.getWorkInfoById(playWorkRequest.id).get()

    wrkMgr.getWorkInfoByIdLiveData(playWorkRequest.id)
        .observe(this, Observer { info ->
            if (info != null && info.state.isFinished) {
                println("The dld-job is done !!!")
            }
        })
}

Below follows the code for the worker:

import ......

class AudioWorker(context: Context, workerParams: WorkerParameters) :
    Worker(context, workerParams) {
    private var audioPlayer:MediaPlayer? = null

    override fun doWork(): Result {
        if (audioPlayer == null) {
            var filePath = "/data/user/0/me.soft.audioserver/app_Audio_Directory/TheAudioFile.mp3"
            audioPlayer = MediaPlayer()
            try {
                audioPlayer?.setDataSource(filePath)
                audioPlayer?.prepare()
                audioPlayer?.setOnCompletionListener({stopAudioPlayer()})
                audioPlayer?.start()
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        return Result.success()
    } /* End of doWork */


    private fun stopAudioPlayer() {
        if (audioPlayer == null) return
        audioPlayer?.release()
        audioPlayer = null
    } /* End of stopAudioPlayer */
}

Am I forgetting something so that it keeps playing to the end of the audio file?


Solution

  • You should not be using the WorkManager but a Service.

    There are two types of services, an intent servicr which is a star and forget, and a regular service. Regular Service are also called bound or binding service because they have to bind with an activity.

    https://developer.android.com/guide/components/bound-services

    The work manager is instended for schedule jobs like in an alarm, for playing music the correct way is the bind service. It will keep playing music in the background, is how every other app does it.