From ec13504009fe29c957ec69313bf206b186bd7713 Mon Sep 17 00:00:00 2001 From: FongMi Date: Fri, 15 May 2026 16:23:35 +0800 Subject: [PATCH] Add repeat button --- .../android/tv/service/PlaybackService.java | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/fongmi/android/tv/service/PlaybackService.java b/app/src/main/java/com/fongmi/android/tv/service/PlaybackService.java index 3ef1d04c6..1d6c3f8cd 100644 --- a/app/src/main/java/com/fongmi/android/tv/service/PlaybackService.java +++ b/app/src/main/java/com/fongmi/android/tv/service/PlaybackService.java @@ -3,6 +3,7 @@ package com.fongmi.android.tv.service; import android.app.PendingIntent; import android.content.Intent; import android.os.Binder; +import android.os.Bundle; import android.os.IBinder; import androidx.annotation.NonNull; @@ -16,7 +17,10 @@ import androidx.media3.session.LibraryResult; import androidx.media3.session.MediaLibraryService; import androidx.media3.session.MediaLibraryService.MediaLibrarySession; import androidx.media3.session.MediaSession; +import androidx.media3.session.SessionCommand; +import androidx.media3.session.SessionCommands; import androidx.media3.session.SessionError; +import androidx.media3.session.SessionResult; import com.fongmi.android.tv.App; import com.fongmi.android.tv.BuildConfig; @@ -45,6 +49,8 @@ public class PlaybackService extends MediaLibraryService implements MediaLibrary public static final String LOCAL_BIND_ACTION = BuildConfig.APPLICATION_ID.concat(".LOCAL_BIND"); + private static final SessionCommand COMMAND_REPEAT = new SessionCommand(ActionEvent.REPEAT, Bundle.EMPTY); + private static volatile boolean running; private final List playerCallbacks = new CopyOnWriteArrayList<>(); @@ -97,16 +103,19 @@ public class PlaybackService extends MediaLibraryService implements MediaLibrary private void setupNotification() { DefaultMediaNotificationProvider provider = new DefaultMediaNotificationProvider.Builder(this).build(); - session.setMediaButtonPreferences(ImmutableList.of(buildStopButton())); + session.setMediaButtonPreferences(ImmutableList.of(buildRepeatButton(), buildStopButton())); provider.setSmallIcon(R.drawable.ic_notification); setMediaNotificationProvider(provider); - } private CommandButton buildStopButton() { return new CommandButton.Builder(CommandButton.ICON_STOP).setPlayerCommand(Player.COMMAND_STOP).setDisplayName(getString(R.string.play_stop)).build(); } + private CommandButton buildRepeatButton() { + return new CommandButton.Builder(player.isRepeatOne() ? CommandButton.ICON_REPEAT_ONE : CommandButton.ICON_REPEAT_OFF).setSessionCommand(COMMAND_REPEAT).setDisplayName(getString(R.string.play_repeat)).build(); + } + @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent != null) handleAction(intent.getAction()); @@ -235,7 +244,18 @@ public class PlaybackService extends MediaLibraryService implements MediaLibrary @NonNull @Override public MediaSession.ConnectionResult onConnect(@NonNull MediaSession session, @NonNull MediaSession.ControllerInfo controller) { - return new MediaLibrarySession.ConnectionResult.AcceptedResultBuilder(session).build(); + SessionCommands commands = new MediaSession.ConnectionResult.AcceptedResultBuilder(session).build().availableSessionCommands.buildUpon().add(COMMAND_REPEAT).build(); + return new MediaLibrarySession.ConnectionResult.AcceptedResultBuilder(session).setAvailableSessionCommands(commands).build(); + } + + @NonNull + @Override + public ListenableFuture onCustomCommand(@NonNull MediaSession session, @NonNull MediaSession.ControllerInfo controller, @NonNull SessionCommand customCommand, @NonNull Bundle args) { + if (COMMAND_REPEAT.customAction.equals(customCommand.customAction)) { + dispatchRepeat(); + return Futures.immediateFuture(new SessionResult(SessionResult.RESULT_SUCCESS)); + } + return MediaLibrarySession.Callback.super.onCustomCommand(session, controller, customCommand, args); } public boolean hasExternalClient() { @@ -462,6 +482,11 @@ public class PlaybackService extends MediaLibraryService implements MediaLibrary public void onPlaybackStateChanged(int state) { if (state == Player.STATE_ENDED && !(hasNavigationCallback() && isNavigationOwner())) navigateItem(1); } + + @Override + public void onRepeatModeChanged(int repeatMode) { + if (session != null) session.setMediaButtonPreferences(ImmutableList.of(buildRepeatButton(), buildStopButton())); + } }; @NonNull