Add Star/Unstar and close Action

Also: Add album to subtitle :)
This commit is contained in:
tzugen 2021-04-21 16:41:08 +02:00
parent 1ee36322db
commit d3b94f3d4c
No known key found for this signature in database
GPG Key ID: 61E9C34BC10EC930
4 changed files with 81 additions and 18 deletions

View File

@ -589,6 +589,18 @@ public class MediaPlayerControllerImpl implements MediaPlayerController
if (mediaPlayerService != null) mediaPlayerService.updateNotification(localMediaPlayer.playerState, localMediaPlayer.currentPlaying); if (mediaPlayerService != null) mediaPlayerService.updateNotification(localMediaPlayer.playerState, localMediaPlayer.currentPlaying);
} }
public void toggleSongStarred() {
if (localMediaPlayer.currentPlaying == null)
return;
final Entry song = localMediaPlayer.currentPlaying.getSong();
// Trigger an update
localMediaPlayer.setCurrentPlaying(localMediaPlayer.currentPlaying);
song.setStarred(!song.getStarred());
}
public void setSongRating(final int rating) public void setSongRating(final int rating)
{ {
if (!KoinJavaComponent.get(FeatureStorage.class).isFeatureEnabled(Feature.FIVE_STAR_RATING)) if (!KoinJavaComponent.get(FeatureStorage.class).isFeatureEnabled(Feature.FIVE_STAR_RATING))

View File

@ -254,6 +254,9 @@ public class MediaPlayerLifecycleSupport
case KeyEvent.KEYCODE_5: case KeyEvent.KEYCODE_5:
mediaPlayerController.setSongRating(5); mediaPlayerController.setSongRating(5);
break; break;
case KeyEvent.KEYCODE_STAR:
mediaPlayerController.toggleSongStarred();
break;
default: default:
break; break;
} }

View File

@ -672,6 +672,7 @@ public class MediaPlayerService extends Service
private Notification buildForegroundNotification(PlayerState playerState, DownloadFile currentPlaying) { private Notification buildForegroundNotification(PlayerState playerState, DownloadFile currentPlaying) {
// Init // Init
Context context = getApplicationContext(); Context context = getApplicationContext();
MusicDirectory.Entry song = (currentPlaying != null) ? currentPlaying.getSong() : null;
// We should use a single notification builder, otherwise the notification may not be updated // We should use a single notification builder, otherwise the notification may not be updated
if (notificationBuilder == null) { if (notificationBuilder == null) {
@ -682,26 +683,15 @@ public class MediaPlayerService extends Service
notificationBuilder.setAutoCancel(false); notificationBuilder.setAutoCancel(false);
notificationBuilder.setOngoing(true); notificationBuilder.setOngoing(true);
notificationBuilder.setOnlyAlertOnce(true); notificationBuilder.setOnlyAlertOnce(true);
notificationBuilder.setWhen(0); notificationBuilder.setWhen(System.currentTimeMillis());
notificationBuilder.setShowWhen(false);
notificationBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC); notificationBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
notificationBuilder.setPriority(NotificationCompat.PRIORITY_LOW); notificationBuilder.setPriority(NotificationCompat.PRIORITY_LOW);
notificationBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
notificationBuilder.setColor(NotificationCompat.COLOR_DEFAULT);
// Add content intent (when user taps on notification) // Add content intent (when user taps on notification)
notificationBuilder.setContentIntent(getPendingIntentForContent()); notificationBuilder.setContentIntent(getPendingIntentForContent());
} }
// Set song title, artist and cover if possible
if (currentPlaying != null) {
MusicDirectory.Entry song = currentPlaying.getSong();
int iconSize = (int) (256 * context.getResources().getDisplayMetrics().density);
Bitmap bitmap = FileUtil.getAlbumArtBitmap(context, song, iconSize, true);
notificationBuilder.setContentTitle(song.getTitle());
notificationBuilder.setContentText(song.getArtist());
notificationBuilder.setLargeIcon(bitmap);
}
// Use the Media Style, to enable native Android support for playback notification // Use the Media Style, to enable native Android support for playback notification
androidx.media.app.NotificationCompat.MediaStyle style = new androidx.media.app.NotificationCompat.MediaStyle(); androidx.media.app.NotificationCompat.MediaStyle style = new androidx.media.app.NotificationCompat.MediaStyle();
style.setMediaSession(mediaSessionToken); style.setMediaSession(mediaSessionToken);
@ -710,19 +700,37 @@ public class MediaPlayerService extends Service
notificationBuilder.clearActions(); notificationBuilder.clearActions();
// Add actions // Add actions
int[] compactActions = addActions(context, notificationBuilder, playerState); int[] compactActions = addActions(context, notificationBuilder, playerState, song);
// Configure shortcut actions
style.setShowActionsInCompactView(compactActions); style.setShowActionsInCompactView(compactActions);
notificationBuilder.setStyle(style); notificationBuilder.setStyle(style);
// Set song title, artist and cover if possible
if (song != null) {
int iconSize = (int) (256 * context.getResources().getDisplayMetrics().density);
Bitmap bitmap = FileUtil.getAlbumArtBitmap(context, song, iconSize, true);
notificationBuilder.setContentTitle(song.getTitle());
notificationBuilder.setContentText(song.getArtist());
notificationBuilder.setLargeIcon(bitmap);
notificationBuilder.setSubText(song.getAlbum());
}
return notificationBuilder.build(); return notificationBuilder.build();
} }
private int[] addActions(Context context, NotificationCompat.Builder notificationBuilder, PlayerState playerState) { private int[] addActions(Context context, NotificationCompat.Builder notificationBuilder, PlayerState playerState, MusicDirectory.Entry song) {
ArrayList<Integer> compactActionList = new ArrayList<>(); ArrayList<Integer> compactActionList = new ArrayList<>();
int numActions = 0; // we start and 0 and then increment by 1 for each call to generateAction int numActions = 0; // we start and 0 and then increment by 1 for each call to generateAction
// Star
if (song != null) {
notificationBuilder.addAction(generateStarUnstarAction(context, numActions, song.getStarred()));
}
numActions++;
// Next // Next
notificationBuilder.addAction(generateAction(context, numActions)); notificationBuilder.addAction(generateAction(context, numActions));
compactActionList.add(numActions); compactActionList.add(numActions);
@ -736,6 +744,10 @@ public class MediaPlayerService extends Service
// Previous // Previous
notificationBuilder.addAction(generateAction(context, numActions)); notificationBuilder.addAction(generateAction(context, numActions));
compactActionList.add(numActions); compactActionList.add(numActions);
numActions++;
// Close
notificationBuilder.addAction(generateAction(context, numActions));
int[] actionArray = new int[compactActionList.size()]; int[] actionArray = new int[compactActionList.size()];
@ -755,19 +767,24 @@ public class MediaPlayerService extends Service
// If you change the order here, also update the requestCode in updatePlayPauseAction()! // If you change the order here, also update the requestCode in updatePlayPauseAction()!
switch (requestCode) { switch (requestCode) {
case 0: case 1:
keycode = KeyEvent.KEYCODE_MEDIA_PREVIOUS; keycode = KeyEvent.KEYCODE_MEDIA_PREVIOUS;
label = getString(R.string.common_play_previous); label = getString(R.string.common_play_previous);
icon = R.drawable.media_backward_medium_dark; icon = R.drawable.media_backward_medium_dark;
break; break;
case 1: case 2:
// Is handled in generatePlayPauseAction() // Is handled in generatePlayPauseAction()
return null; return null;
case 2: case 3:
keycode = KeyEvent.KEYCODE_MEDIA_NEXT; keycode = KeyEvent.KEYCODE_MEDIA_NEXT;
label = getString(R.string.common_play_next); label = getString(R.string.common_play_next);
icon = R.drawable.media_forward_medium_dark; icon = R.drawable.media_forward_medium_dark;
break; break;
case 4:
keycode = KeyEvent.KEYCODE_MEDIA_STOP;
label = getString(R.string.buttons_stop);
icon = R.drawable.ic_baseline_close_24;
break;
default: default:
return null; return null;
} }
@ -797,6 +814,28 @@ public class MediaPlayerService extends Service
} }
private NotificationCompat.Action generateStarUnstarAction(Context context, int requestCode, Boolean isStarred) {
int keyCode;
String label;
int icon;
keyCode = KeyEvent.KEYCODE_STAR;
if (isStarred) {
label = getString(R.string.download_menu_star);
icon = R.drawable.ic_star_full_dark;
} else {
label = getString(R.string.download_menu_star);
icon = R.drawable.ic_star_hollow_dark;
}
PendingIntent pendingIntent = getPendingIntentForMediaAction(context, keyCode, requestCode);
return new NotificationCompat.Action.Builder(icon, label, pendingIntent).build();
}
private PendingIntent getPendingIntentForContent() { private PendingIntent getPendingIntentForContent() {
Intent notificationIntent = new Intent(this, NavigationActivity.class) Intent notificationIntent = new Intent(this, NavigationActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>