1

I'm developing an android app that is mostly run in the background and uses Firebase Realtime Database for data syncing.

I want the app to play a 10 second sound when new data is received from Firebase and I've successfully managed to implement this, however, my solution doesn't work on all devices.

Here's my code:

class MyViewModel constructor(
   
) : ViewModel() {
   private var mediaPlayer: MediaPlayer? = null

   fun initRtdListener(context: Context) {
      val ref = Firebase.database.getReference("my-path")
      mediaPlayer = MediaPlayer.create(context, R.raw.my_short_audio)

      ref.addValueEventListener(object : ValueEventListener {
          override fun onDataChange(dataSnapshot: DataSnapshot) {                
            mediaPlayer?.start()
          }

          override fun onCancelled(error: DatabaseError) {}
      })
   }
}

This solution works perfectly on most devices even when the app is running in the background, however, on some devices (like Realme X) the sound is played only when the app is in foreground. What could be the problem? Is it because I play the sound not in the context of a service? If yes, do I really need a service considering that my sounds are short?

P.S. I have two background services which are working without any issues on all devices

Bravo
  • 1,944
  • 4
  • 29
  • 53
  • "This solution works perfectly on most devices even when the app is running in the background" -- only if the activity or fragment that loaded the viewmodel has not been destroyed, and only if your process is still running. "What could be the problem?" -- your app's process can be terminated at any point while it is in the background. On some devices, this could be within seconds of going to the background, [even if you have a service](https://dontkillmyapp.com/). – CommonsWare Jan 02 '23 at 19:47
  • If your app is in the background, the system can kill its process at any time. Some devices (e.g. ones using MIUI) have aggressive power-saving behaviour by default, and sometimes users install apps that perform similar actions. So basically, *you can't expect your app to stay running when it's not in the foreground*. If you want to do background work, you'll either need to run a foreground service (confusingly named but it runs "as if it's in the foreground"), use things like WorkManager, or use a receiver to react to Intents (where you'll have a short window to do things like play a sound) – cactustictacs Jan 02 '23 at 19:51
  • Thank you for your replies. I have one foreground and one background service launched from the same Activity as the RTD listener via viewmodel. Does this mean that I should start the RTD listener in a service instead of viewmodel and play audio from there? If yes, how can I handle business logic if my viewmodel will be killed by the OS? – Bravo Jan 03 '23 at 15:35

0 Answers0