diff --git a/demos/session/src/main/java/androidx/media3/demo/session/PlayableFolderActivity.kt b/demos/session/src/main/java/androidx/media3/demo/session/PlayableFolderActivity.kt index 7a910fd8670..f1c1631d451 100644 --- a/demos/session/src/main/java/androidx/media3/demo/session/PlayableFolderActivity.kt +++ b/demos/session/src/main/java/androidx/media3/demo/session/PlayableFolderActivity.kt @@ -30,6 +30,7 @@ import android.widget.ListView import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.media3.common.MediaItem +import androidx.media3.common.Player import androidx.media3.session.MediaBrowser import androidx.media3.session.SessionToken import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton @@ -179,6 +180,9 @@ class PlayableFolderActivity : AppCompatActivity() { returnConvertView.findViewById(R.id.add_button).setOnClickListener { val browser = this@PlayableFolderActivity.browser ?: return@setOnClickListener browser.addMediaItem(mediaItem) + if (browser.playbackState == Player.STATE_IDLE) { + browser.prepare() + } Snackbar.make( findViewById(R.id.linear_layout), getString(R.string.added_media_item_format, mediaItem.mediaMetadata.title), diff --git a/demos/session/src/main/java/androidx/media3/demo/session/PlaybackService.kt b/demos/session/src/main/java/androidx/media3/demo/session/PlaybackService.kt index 6efe76bccc0..b4ec76ee5a8 100644 --- a/demos/session/src/main/java/androidx/media3/demo/session/PlaybackService.kt +++ b/demos/session/src/main/java/androidx/media3/demo/session/PlaybackService.kt @@ -96,7 +96,6 @@ class PlaybackService : MediaLibraryService() { val item = MediaItemTree.getItemFromTitle(mediaTitle) ?: MediaItemTree.getRandomItem() player.setMediaItem(item) - player.prepare() } override fun onSetMediaUri( diff --git a/libraries/session/src/main/java/androidx/media3/session/DefaultMediaNotificationProvider.java b/libraries/session/src/main/java/androidx/media3/session/DefaultMediaNotificationProvider.java index 1b308d425ab..492a6a116ea 100644 --- a/libraries/session/src/main/java/androidx/media3/session/DefaultMediaNotificationProvider.java +++ b/libraries/session/src/main/java/androidx/media3/session/DefaultMediaNotificationProvider.java @@ -31,6 +31,7 @@ import androidx.core.app.NotificationCompat; import androidx.core.graphics.drawable.IconCompat; import androidx.media3.common.MediaMetadata; +import androidx.media3.common.Player; import androidx.media3.common.util.Consumer; import androidx.media3.common.util.Log; import androidx.media3.common.util.UnstableApi; @@ -120,20 +121,21 @@ public MediaNotification createNotification( IconCompat.createWithResource(context, R.drawable.media3_notification_seek_to_previous), context.getString(R.string.media3_controls_seek_to_previous_description), MediaNotification.ActionFactory.COMMAND_SKIP_TO_PREVIOUS)); - if (mediaController.getPlayWhenReady()) { - // Pause action. - builder.addAction( - actionFactory.createMediaAction( - IconCompat.createWithResource(context, R.drawable.media3_notification_pause), - context.getString(R.string.media3_controls_pause_description), - MediaNotification.ActionFactory.COMMAND_PAUSE)); - } else { + if (mediaController.getPlaybackState() == Player.STATE_ENDED + || !mediaController.getPlayWhenReady()) { // Play action. builder.addAction( actionFactory.createMediaAction( IconCompat.createWithResource(context, R.drawable.media3_notification_play), context.getString(R.string.media3_controls_play_description), MediaNotification.ActionFactory.COMMAND_PLAY)); + } else { + // Pause action. + builder.addAction( + actionFactory.createMediaAction( + IconCompat.createWithResource(context, R.drawable.media3_notification_pause), + context.getString(R.string.media3_controls_pause_description), + MediaNotification.ActionFactory.COMMAND_PAUSE)); } // Skip to next action. builder.addAction( diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaNotificationManager.java b/libraries/session/src/main/java/androidx/media3/session/MediaNotificationManager.java index c89ebe092d0..7d3ceac3bb5 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaNotificationManager.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaNotificationManager.java @@ -196,7 +196,9 @@ public void onConnected() { @Override public void onEvents(Player player, Player.Events events) { if (events.containsAny( - Player.EVENT_PLAY_WHEN_READY_CHANGED, Player.EVENT_MEDIA_METADATA_CHANGED)) { + Player.EVENT_PLAYBACK_STATE_CHANGED, + Player.EVENT_PLAY_WHEN_READY_CHANGED, + Player.EVENT_MEDIA_METADATA_CHANGED)) { updateNotification(session); } } diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaSessionLegacyStub.java b/libraries/session/src/main/java/androidx/media3/session/MediaSessionLegacyStub.java index 2aef615164e..41219049558 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaSessionLegacyStub.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaSessionLegacyStub.java @@ -28,6 +28,8 @@ import static androidx.media3.common.Player.COMMAND_SET_SHUFFLE_MODE; import static androidx.media3.common.Player.COMMAND_SET_SPEED_AND_PITCH; import static androidx.media3.common.Player.COMMAND_STOP; +import static androidx.media3.common.Player.STATE_ENDED; +import static androidx.media3.common.Player.STATE_IDLE; import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.common.util.Assertions.checkStateNotNull; import static androidx.media3.common.util.Util.postOrRun; @@ -231,7 +233,17 @@ private void handleMediaPlayPauseOnHandler(RemoteUserInfo remoteUserInfo) { } else { dispatchSessionTaskWithPlayerCommand( COMMAND_PLAY_PAUSE, - (controller) -> sessionImpl.getPlayerWrapper().play(), + (controller) -> { + PlayerWrapper playerWrapper = sessionImpl.getPlayerWrapper(); + @Player.State int playbackState = playerWrapper.getPlaybackState(); + if (playbackState == STATE_IDLE) { + playerWrapper.prepare(); + } else if (playbackState == STATE_ENDED) { + playerWrapper.seekTo( + playerWrapper.getCurrentMediaItemIndex(), /* positionMs= */ C.TIME_UNSET); + } + playerWrapper.play(); + }, remoteUserInfo); } } @@ -285,7 +297,17 @@ public void onPrepareFromUri(Uri mediaUri, @Nullable Bundle extras) { public void onPlay() { dispatchSessionTaskWithPlayerCommand( COMMAND_PLAY_PAUSE, - controller -> sessionImpl.getPlayerWrapper().play(), + controller -> { + PlayerWrapper playerWrapper = sessionImpl.getPlayerWrapper(); + @Player.State int playbackState = playerWrapper.getPlaybackState(); + if (playbackState == Player.STATE_IDLE) { + playerWrapper.prepare(); + } else if (playbackState == Player.STATE_ENDED) { + playerWrapper.seekTo( + playerWrapper.getCurrentMediaItemIndex(), /* positionMs= */ C.TIME_UNSET); + } + playerWrapper.play(); + }, sessionCompat.getCurrentControllerInfo()); } @@ -321,7 +343,15 @@ public void onPlayFromUri(Uri mediaUri, @Nullable Bundle extras) { if (sessionImpl.onSetMediaUriOnHandler( controller, mediaUri, extras == null ? Bundle.EMPTY : extras) == RESULT_SUCCESS) { - sessionImpl.getPlayerWrapper().play(); + PlayerWrapper playerWrapper = sessionImpl.getPlayerWrapper(); + @Player.State int playbackState = playerWrapper.getPlaybackState(); + if (playbackState == Player.STATE_IDLE) { + playerWrapper.prepare(); + } else if (playbackState == STATE_ENDED) { + playerWrapper.seekTo( + playerWrapper.getCurrentMediaItemIndex(), /* positionMs= */ C.TIME_UNSET); + } + playerWrapper.play(); } }); }