diff options
author | Matej Drobnič <matej@matejdro.com> | 2024-02-04 19:54:46 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-04 19:54:46 +0100 |
commit | 0f5600932d5894d5653993d48d925df437fe6d00 (patch) | |
tree | ee34151ac28bbe55dcec9c45de1cb5dbe92ad299 /core/src | |
parent | f0e96a269233e85a452eabcbfe09899157024ab3 (diff) | |
download | AntennaPod-0f5600932d5894d5653993d48d925df437fe6d00.zip |
Add next chapter button to notification (#6276)
Diffstat (limited to 'core/src')
4 files changed, 106 insertions, 31 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/receiver/MediaButtonReceiver.java b/core/src/main/java/de/danoeh/antennapod/core/receiver/MediaButtonReceiver.java index 08bdd39bc..161af58e1 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/receiver/MediaButtonReceiver.java +++ b/core/src/main/java/de/danoeh/antennapod/core/receiver/MediaButtonReceiver.java @@ -17,6 +17,8 @@ import de.danoeh.antennapod.core.ClientConfigurator; public class MediaButtonReceiver extends BroadcastReceiver { private static final String TAG = "MediaButtonReceiver"; public static final String EXTRA_KEYCODE = "de.danoeh.antennapod.core.service.extra.MediaButtonReceiver.KEYCODE"; + public static final String EXTRA_CUSTOM_ACTION = + "de.danoeh.antennapod.core.service.extra.MediaButtonReceiver.CUSTOM_ACTION"; public static final String EXTRA_SOURCE = "de.danoeh.antennapod.core.service.extra.MediaButtonReceiver.SOURCE"; public static final String EXTRA_HARDWAREBUTTON = "de.danoeh.antennapod.core.service.extra.MediaButtonReceiver.HARDWAREBUTTON"; diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java index 3ef2e2214..b26cf4814 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java @@ -47,6 +47,20 @@ import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; import androidx.media.MediaBrowserServiceCompat; +import de.danoeh.antennapod.core.service.QuickSettingsTileService; +import de.danoeh.antennapod.core.util.ChapterUtils; +import de.danoeh.antennapod.core.util.playback.PlayableUtils; +import de.danoeh.antennapod.event.playback.BufferUpdateEvent; +import de.danoeh.antennapod.event.playback.PlaybackServiceEvent; +import de.danoeh.antennapod.event.PlayerErrorEvent; +import de.danoeh.antennapod.event.playback.SleepTimerUpdatedEvent; +import de.danoeh.antennapod.model.feed.Chapter; +import de.danoeh.antennapod.model.feed.FeedItemFilter; +import de.danoeh.antennapod.playback.base.PlaybackServiceMediaPlayer; +import de.danoeh.antennapod.playback.base.PlayerStatus; +import de.danoeh.antennapod.playback.cast.CastPsmp; +import de.danoeh.antennapod.playback.cast.CastStateListener; + import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; @@ -126,6 +140,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { private static final String CUSTOM_ACTION_REWIND = "action.de.danoeh.antennapod.core.service.rewind"; private static final String CUSTOM_ACTION_CHANGE_PLAYBACK_SPEED = "action.de.danoeh.antennapod.core.service.changePlaybackSpeed"; + public static final String CUSTOM_ACTION_NEXT_CHAPTER = "action.de.danoeh.antennapod.core.service.next_chapter"; /** * Set a max number of episodes to load for Android Auto, otherwise there could be performance issues @@ -482,9 +497,10 @@ public class PlaybackService extends MediaBrowserServiceCompat { notificationManager.cancel(R.id.notification_streaming_confirmation); final int keycode = intent.getIntExtra(MediaButtonReceiver.EXTRA_KEYCODE, -1); + final String customAction = intent.getStringExtra(MediaButtonReceiver.EXTRA_CUSTOM_ACTION); final boolean hardwareButton = intent.getBooleanExtra(MediaButtonReceiver.EXTRA_HARDWAREBUTTON, false); Playable playable = intent.getParcelableExtra(PlaybackServiceInterface.EXTRA_PLAYABLE); - if (keycode == -1 && playable == null) { + if (keycode == -1 && playable == null && customAction == null) { Log.e(TAG, "PlaybackService was started with no arguments"); stateManager.stopService(); return Service.START_NOT_STICKY; @@ -508,7 +524,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { stateManager.stopService(); return Service.START_NOT_STICKY; } - } else { + } else if (playable != null) { stateManager.validStartCommandWasReceived(); boolean allowStreamThisTime = intent.getBooleanExtra( PlaybackServiceInterface.EXTRA_ALLOW_STREAM_THIS_TIME, false); @@ -536,6 +552,8 @@ public class PlaybackService extends MediaBrowserServiceCompat { stateManager.stopService(); }); return Service.START_NOT_STICKY; + } else { + mediaSession.getController().getTransportControls().sendCustomAction(customAction, null); } } @@ -783,6 +801,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { @Override public void onChapterLoaded(Playable media) { sendNotificationBroadcast(PlaybackServiceInterface.NOTIFICATION_TYPE_RELOAD, 0); + updateMediaSession(mediaPlayer.getPlayerStatus()); } }; @@ -1250,20 +1269,35 @@ public class PlaybackService extends MediaBrowserServiceCompat { WearMediaSession.addWearExtrasToAction(fastForwardBuilder); sessionState.addCustomAction(fastForwardBuilder.build()); - sessionState.addCustomAction( - new PlaybackStateCompat.CustomAction.Builder( - CUSTOM_ACTION_CHANGE_PLAYBACK_SPEED, - getString(R.string.playback_speed), - R.drawable.ic_notification_playback_speed + if (UserPreferences.showPlaybackSpeedOnFullNotification()) { + sessionState.addCustomAction( + new PlaybackStateCompat.CustomAction.Builder( + CUSTOM_ACTION_CHANGE_PLAYBACK_SPEED, + getString(R.string.playback_speed), + R.drawable.ic_notification_playback_speed ).build() - ); - sessionState.addCustomAction( + ); + } + + if (UserPreferences.showNextChapterOnFullNotification()) { + if (getPlayable() != null && getPlayable().getChapters() != null) { + sessionState.addCustomAction( + new PlaybackStateCompat.CustomAction.Builder( + CUSTOM_ACTION_NEXT_CHAPTER, + getString(R.string.next_chapter), R.drawable.ic_notification_next_chapter) + .build()); + } + } + + if (UserPreferences.showSkipOnFullNotification()) { + sessionState.addCustomAction( new PlaybackStateCompat.CustomAction.Builder( - CUSTOM_ACTION_SKIP_TO_NEXT, - getString(R.string.skip_episode_label), - R.drawable.ic_notification_skip + CUSTOM_ACTION_SKIP_TO_NEXT, + getString(R.string.skip_episode_label), + R.drawable.ic_notification_skip ).build() - ); + ); + } WearMediaSession.mediaSessionSetExtraForWear(mediaSession); @@ -1812,6 +1846,26 @@ public class PlaybackService extends MediaBrowserServiceCompat { seekDelta(-UserPreferences.getRewindSecs() * 1000); } + public void onNextChapter() { + List<Chapter> chapters = mediaPlayer.getPlayable().getChapters(); + if (chapters == null) { + // No chapters, just fallback to next episode + mediaPlayer.skip(); + return; + } + + int nextChapter = ChapterUtils.getCurrentChapterIndex( + mediaPlayer.getPlayable(), mediaPlayer.getPosition()) + 1; + + if (chapters.size() < nextChapter + 1) { + // We are on the last chapter, just fallback to the next episode + mediaPlayer.skip(); + return; + } + + mediaPlayer.seekTo((int) chapters.get(nextChapter).getStart()); + } + @Override public void onFastForward() { Log.d(TAG, "onFastForward()"); @@ -1884,6 +1938,8 @@ public class PlaybackService extends MediaBrowserServiceCompat { onRewind(); } else if (CUSTOM_ACTION_SKIP_TO_NEXT.equals(action)) { mediaPlayer.skip(); + } else if (CUSTOM_ACTION_NEXT_CHAPTER.equals(action)) { + onNextChapter(); } else if (CUSTOM_ACTION_CHANGE_PLAYBACK_SPEED.equals(action)) { List<Float> selectedSpeeds = UserPreferences.getPlaybackSpeedArray(); diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceNotificationBuilder.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceNotificationBuilder.java index fe98dbc8f..471dc7454 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceNotificationBuilder.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceNotificationBuilder.java @@ -175,14 +175,12 @@ public class PlaybackServiceNotificationBuilder { ArrayList<Integer> compactActionList = new ArrayList<>(); int numActions = 0; // we start and 0 and then increment by 1 for each call to addAction - // always let them rewind + PendingIntent rewindButtonPendingIntent = getPendingIntentForMediaAction( KeyEvent.KEYCODE_MEDIA_REWIND, numActions); notification.addAction(R.drawable.ic_notification_fast_rewind, context.getString(R.string.rewind_label), rewindButtonPendingIntent); - if (UserPreferences.showRewindOnCompactNotification()) { - compactActionList.add(numActions); - } + compactActionList.add(numActions); numActions++; if (playerStatus == PlayerStatus.PLAYING) { @@ -205,19 +203,24 @@ public class PlaybackServiceNotificationBuilder { KeyEvent.KEYCODE_MEDIA_FAST_FORWARD, numActions); notification.addAction(R.drawable.ic_notification_fast_forward, context.getString(R.string.fast_forward_label), ffButtonPendingIntent); - if (UserPreferences.showFastForwardOnCompactNotification()) { - compactActionList.add(numActions); - } + compactActionList.add(numActions); numActions++; - PendingIntent skipButtonPendingIntent = getPendingIntentForMediaAction( - KeyEvent.KEYCODE_MEDIA_NEXT, numActions); - notification.addAction(R.drawable.ic_notification_skip, context.getString(R.string.skip_episode_label), - skipButtonPendingIntent); - if (UserPreferences.showSkipOnCompactNotification()) { - compactActionList.add(numActions); + if (UserPreferences.showNextChapterOnFullNotification() && playable.getChapters() != null) { + PendingIntent nextChapterPendingIntent = getPendingIntentForCustomMediaAction( + PlaybackService.CUSTOM_ACTION_NEXT_CHAPTER, numActions); + notification.addAction(R.drawable.ic_notification_next_chapter, context.getString(R.string.next_chapter), + nextChapterPendingIntent); + numActions++; + } + + if (UserPreferences.showSkipOnFullNotification()) { + PendingIntent skipButtonPendingIntent = getPendingIntentForMediaAction( + KeyEvent.KEYCODE_MEDIA_NEXT, numActions); + notification.addAction(R.drawable.ic_notification_skip, context.getString(R.string.skip_episode_label), + skipButtonPendingIntent); + numActions++; } - numActions++; PendingIntent stopButtonPendingIntent = getPendingIntentForMediaAction( KeyEvent.KEYCODE_MEDIA_STOP, numActions); @@ -242,6 +245,20 @@ public class PlaybackServiceNotificationBuilder { } } + private PendingIntent getPendingIntentForCustomMediaAction(String action, int requestCode) { + Intent intent = new Intent(context, PlaybackService.class); + intent.setAction("MediaAction" + action); + intent.putExtra(MediaButtonReceiver.EXTRA_CUSTOM_ACTION, action); + + if (Build.VERSION.SDK_INT >= 26) { + return PendingIntent.getForegroundService(context, requestCode, intent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + return PendingIntent.getService(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT + | (Build.VERSION.SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0)); + } + } + public void setMediaSessionToken(MediaSessionCompat.Token mediaSessionToken) { this.mediaSessionToken = mediaSessionToken; } @@ -253,4 +270,4 @@ public class PlaybackServiceNotificationBuilder { public PlayerStatus getPlayerStatus() { return playerStatus; } -}
\ No newline at end of file +} diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml index f72a2e108..7eeab886a 100644 --- a/core/src/main/res/values/arrays.xml +++ b/core/src/main/res/values/arrays.xml @@ -246,10 +246,10 @@ <item>DownloadsSection</item> </string-array> - <string-array name="compact_notification_buttons_options"> - <item>@string/rewind_label</item> - <item>@string/fast_forward_label</item> + <string-array name="full_notification_buttons_options"> <item>@string/skip_episode_label</item> + <item>@string/next_chapter</item> + <item>@string/playback_speed</item> </string-array> <string-array name="default_page_values"> |