Search code examples
androidbackgroundandroid-8.0-oreoandroid-jobschedulerringtone

What is the best/correct way to play/stop a ringtone on Android 8+ even when the app is in the background?


First some background info

I had a problem with starting a background service when the app is in the background in Android 8+. The documentation clearly describes the new limitations for backgroud execution.

So I went ahead and implemented my service as a JobIntentService (the recommended way for simple cases). This seems to work well...for the first error I got anyway.

Playing a ringtone...should be easy

Before Android 8, our app was using a background service to play a ringtone using RingtoneManager (starting playback in onStartCommand() and stopping when the service is stopped). This worked pretty well.

Because of the new background execution limits, I tried to use the JobIntentService for this task as well but noticed it can't be explicitly stopped. OK, so I tried with JobScheduler and a JobService (since as I understand it JobIntentService should basically do the same thing without the hassle of creating the JobInfo). I don't have any special requirements, so I went with the same stuff used by JobIntentService (setOverrideDeadline(0)).

The JobService is started, but it's immediately stopped by the system even when I return true from onStartJob(). I'm looking into this - maybe I'm doing something wrong there.

...or is it?

  • I also considered a bound service, but it seems weird since I also need to call it from another service (but maybe this would be OK). Bound services are not influenced by the background limitations so maybe this would be the right way.
  • A regular background service worked fine before Android 8, but I obviously can't use that.
  • I don't think a foreground service is the way to go for simple ringtones.
  • I even played with the idea of trying to raise the app to the foreground to go around the problem, but from googling around, this feels more like a hack than a proper solution.

This should be simple right?

I'm a little perplexed by the fact that the simple matter of playing and stopping a ringtone doesn't seem to be dead simple including the background stuff (if I have an app with some kind of calling capability, I just need this to work, so why should I need to mess with this and reinvent the wheel here?).

I'm not primarily an Android developer, so I might be missing some important obvious things. I tried googling this to no end and I got tons of examples of how to play stuff using RingtoneManager and even MediaPlayer or some such, but I didn't see any mention of the background problem.

Any input is appreciated, thanx.


Solution

  • I ended up using a foreground service to play the ringtone. I can still stop the service and the service is allowed to start from the background.

    The stock android phone app also shows a notification for a call so maybe they do the same thing here.