1

I've createde a simple app (following this link How to Play Sound On Button Click in Android Studio Java 2021 ), and everything works fine, but, i need this app can still playing the sound after minimize then or block the phone (is a white noise app from help on sleep for my baby daughter, and i need that keep playing all night).

Is there any way or setting that allows the sound not to stop after minimizing or blocking the application?

Thank you for enveryone that could help me and my baby :)

1 Answers1

2

If you add the ability to run your application in the background, it will solve your problem. Resources you can review:

Basic Example :

AndroidManifest.xml :

    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
*
*
*
*
        <service android:name=".ui.main.AudioPlayerService"/>

 </application>

AudioPlayerService :

    private const val PLAYBACK_CHANNEL_ID = "blabla"
        private const val PLAYBACK_NOTIFICATION_ID = 1
        
        class AudioPlayerService : Service() {
        
            private var player: SimpleExoPlayer? = null
            private var playerNotificationManager: PlayerNotificationManager? = null
            private val mediaItem: MediaItem = MediaItem.fromUri(ApiInterface.Channel24LiveURL)
        
            /** Classes to be connected to the service with the 
             service
             *reference providing the link between
             */
            private val mBinder = AudioServiceBinder()
        
            /**
* Data that the service will share to other classes.             */
            inner class AudioServiceBinder : Binder() {
                val service
                    get() = this@AudioPlayerService
        
                val player
                    get() = this@AudioPlayerService.player
            }
        
            override fun onBind(intent: Intent?): IBinder? {
                return mBinder
            }
        
            /**
             * Service start part
             */
            override fun onCreate() {
                super.onCreate()
        
                // init player
                player = SimpleExoPlayer.Builder(this)
                        .build().apply {
                            setMediaItem(mediaItem)
                            playWhenReady = true
                            prepare()
                        }
        
                playerNotificationManager = PlayerNotificationManager.createWithNotificationChannel(
                        applicationContext,
                        PLAYBACK_CHANNEL_ID,
                        R.string.playback_channel_name,
                        R.string.playback_channel_desc,
                        PLAYBACK_NOTIFICATION_ID,
                        object : PlayerNotificationManager.MediaDescriptionAdapter {
                            override fun getCurrentContentTitle(player: Player): CharSequence {
                                return getString(R.string.def_playback_title)
                            }
        
                            override fun createCurrentContentIntent(player: Player): PendingIntent? {
                                return PendingIntent.getActivity(
                                        applicationContext,
                                        0,
                                        Intent(applicationContext, MainActivity::class.java),
                                        PendingIntent.FLAG_CANCEL_CURRENT
                                )
                            }
        
                            override fun getCurrentContentText(player: Player): CharSequence? {
                                return null
                            }
        
                            override fun getCurrentLargeIcon(
                                    player: Player,
                                    callback: PlayerNotificationManager.BitmapCallback
                            ): Bitmap? {
                                return getBitmapFromVectorDrawable(applicationContext, R.mipmap.ic_launcher)
                            }
                        }, object : PlayerNotificationManager.NotificationListener {
                    override fun onNotificationCancelled(notificationId: Int, dismissedByUser: Boolean) {
                        stopSelf()
                    }
        
                    override fun onNotificationPosted(notificationId: Int, notification: Notification, ongoing: Boolean) {
                        if (ongoing) {
                            // Make sure the service will not get destroyed while playing media.
                            startForeground(notificationId, notification)
                        } else {
                            // Make notification cancellable.
                            stopForeground(false)
                        }
                    }
                }
                ).apply {
                    //   previous and next actions.
                    setUseNavigationActions(true)
                    setPlayer(player)
                }
            }
        
            @MainThread
            private fun getBitmapFromVectorDrawable(
                    context: Context,
                    @Suppress("SameParameterValue") @DrawableRes drawableId: Int
            ): Bitmap? {
                return ContextCompat.getDrawable(context, drawableId)?.let {
                    val drawable = DrawableCompat.wrap(it).mutate()
        
                    val bitmap = Bitmap.createBitmap(
                            drawable.intrinsicWidth,
                            drawable.intrinsicHeight,
                            Bitmap.Config.ARGB_8888
                    )
                    val canvas = Canvas(bitmap)
                    drawable.setBounds(0, 0, canvas.width, canvas.height)
                    drawable.draw(canvas)
        
                    bitmap
                }
            }
        
            @MainThread
            fun changePlayerVolume(view: ImageView) {
                player?.let {
                    if (it.volume == 1.0f) {
                        it.volume = 0.0f
                        view.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_volume_off))
                    } else {
                        it.volume = 1.0f
                        view.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_volume_up))
                    }
                }
            }
        
            @MainThread
            fun jumpLiveStream() {
                player?.let {
                    it.setMediaItem(mediaItem)
                    it.playWhenReady = true
                }
            }
        
            /**
* Triggered when the app is closed.             */
            override fun onTaskRemoved(rootIntent: Intent?) {// Stop the service when the user closes the application.l
                releasePlayer()
                stopSelf()
                super.onTaskRemoved(rootIntent)
            }
        
            override fun onDestroy() {
                releasePlayer()
                stopSelf()
                super.onDestroy()
            }
        
            /**
* delete player and playerNotificationManager             */
            private fun releasePlayer() {
                player?.let {
                    it.release()
                    player = null
                }
                playerNotificationManager?.let {
                    it.setPlayer(null)
                    playerNotificationManager = null
                }
            }
        }

Good luck!

Halil Ozel
  • 2,482
  • 3
  • 17
  • 32
Nisa Efendioglu
  • 901
  • 3
  • 12
  • 22