@@ -743,8 +743,17 @@ class StreamFragment : Fragment(), Player.Listener {
743743 if (sleepTimer == null ) {
744744 sleepTimer = SleepTimer (object : SleepTimerDelegate {
745745 override fun onTimesUp () {
746- stopAudioOnly()
747- player!! .pause()
746+ // If in audio-only mode, just disable the view without restarting the stream
747+ if (isAudioOnlyModeEnabled) {
748+ disableAudioOnlyView()
749+ }
750+ // Pause the current player
751+ if (player != null ) {
752+ player?.pause()
753+ } else {
754+ // App is minimized - connect to PlaybackService to pause
755+ pausePlaybackService()
756+ }
748757 }
749758
750759 override fun onStart (message : String ) {
@@ -760,6 +769,33 @@ class StreamFragment : Fragment(), Player.Listener {
760769 sleepTimer!! .show(requireActivity())
761770 }
762771
772+ /* *
773+ * Connects to the PlaybackService and pauses playback.
774+ * Used when the sleep timer fires while the app is minimized.
775+ */
776+ private fun pausePlaybackService () {
777+ val context = context ? : return
778+ val sessionToken = SessionToken (
779+ context,
780+ ComponentName (context, PlaybackService ::class .java)
781+ )
782+ val future = MediaController .Builder (context, sessionToken).buildAsync()
783+ Futures .addCallback(
784+ future,
785+ object : FutureCallback <MediaController > {
786+ override fun onSuccess (controller : MediaController ? ) {
787+ controller?.pause()
788+ MediaController .releaseFuture(future)
789+ }
790+
791+ override fun onFailure (t : Throwable ) {
792+ Timber .e(t, " SleepTimer: Failed to connect to PlaybackService" )
793+ }
794+ },
795+ ContextCompat .getMainExecutor(context)
796+ )
797+ }
798+
763799 private fun playbackButtonClicked () {
764800 DialogService .getPlaybackDialog(requireActivity(), player!! ).show()
765801 }
0 commit comments