From 4e8c3694d4c27ffb2be16ee4502eb8243501a64f Mon Sep 17 00:00:00 2001 From: Karim Abou Zeid Date: Mon, 15 Jun 2015 20:51:55 +0200 Subject: [PATCH] Amend last commit. Added new drawables and removed obsolete drawables and layouts. --- .../gramophone/helper/MediaSessionHelper.java | 70 +++++ .../helper/PlayingNotificationHelper.java | 240 ++++++------------ .../gramophone/service/MusicService.java | 136 +++++----- .../res/drawable-hdpi/ic_pause_white_36dp.png | Bin 0 -> 158 bytes .../res/drawable-hdpi/ic_pause_white_48dp.png | Bin 215 -> 0 bytes .../ic_play_arrow_white_36dp.png | Bin 0 -> 294 bytes .../ic_play_arrow_white_48dp.png | Bin 399 -> 0 bytes .../drawable-hdpi/ic_skip_next_white_36dp.png | Bin 0 -> 304 bytes .../ic_skip_previous_white_36dp.png | Bin 0 -> 334 bytes .../res/drawable-mdpi/ic_pause_white_36dp.png | Bin 0 -> 126 bytes .../res/drawable-mdpi/ic_pause_white_48dp.png | Bin 193 -> 0 bytes .../ic_play_arrow_white_36dp.png | Bin 0 -> 231 bytes .../ic_play_arrow_white_48dp.png | Bin 318 -> 0 bytes .../drawable-mdpi/ic_skip_next_white_36dp.png | Bin 0 -> 216 bytes .../ic_skip_previous_white_36dp.png | Bin 0 -> 235 bytes .../drawable-xhdpi/ic_pause_white_36dp.png | Bin 0 -> 183 bytes .../drawable-xhdpi/ic_pause_white_48dp.png | Bin 256 -> 0 bytes .../ic_play_arrow_white_36dp.png | Bin 0 -> 367 bytes .../ic_play_arrow_white_48dp.png | Bin 477 -> 0 bytes .../ic_skip_next_white_36dp.png | Bin 0 -> 368 bytes .../ic_skip_previous_white_36dp.png | Bin 0 -> 373 bytes .../drawable-xxhdpi/ic_pause_white_36dp.png | Bin 0 -> 285 bytes .../drawable-xxhdpi/ic_pause_white_48dp.png | Bin 352 -> 0 bytes .../ic_play_arrow_white_36dp.png | Bin 0 -> 490 bytes .../ic_play_arrow_white_48dp.png | Bin 666 -> 0 bytes .../ic_skip_next_white_36dp.png | Bin 0 -> 543 bytes .../ic_skip_previous_white_36dp.png | Bin 0 -> 552 bytes .../drawable-xxxhdpi/ic_pause_white_36dp.png | Bin 0 -> 431 bytes .../drawable-xxxhdpi/ic_pause_white_48dp.png | Bin 436 -> 0 bytes .../ic_play_arrow_white_36dp.png | Bin 0 -> 651 bytes .../ic_play_arrow_white_48dp.png | Bin 835 -> 0 bytes .../ic_skip_next_white_36dp.png | Bin 0 -> 749 bytes .../ic_skip_previous_white_36dp.png | Bin 0 -> 728 bytes .../res/layout-v21/notification_playing.xml | 88 ------- .../notification_playing_expanded.xml | 114 --------- .../main/res/layout/notification_playing.xml | 88 ------- .../layout/notification_playing_expanded.xml | 121 --------- 37 files changed, 222 insertions(+), 635 deletions(-) create mode 100644 app/src/main/java/com/kabouzeid/gramophone/helper/MediaSessionHelper.java create mode 100644 app/src/main/res/drawable-hdpi/ic_pause_white_36dp.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_pause_white_48dp.png create mode 100644 app/src/main/res/drawable-hdpi/ic_play_arrow_white_36dp.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_play_arrow_white_48dp.png create mode 100644 app/src/main/res/drawable-hdpi/ic_skip_next_white_36dp.png create mode 100644 app/src/main/res/drawable-hdpi/ic_skip_previous_white_36dp.png create mode 100644 app/src/main/res/drawable-mdpi/ic_pause_white_36dp.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_pause_white_48dp.png create mode 100644 app/src/main/res/drawable-mdpi/ic_play_arrow_white_36dp.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_play_arrow_white_48dp.png create mode 100644 app/src/main/res/drawable-mdpi/ic_skip_next_white_36dp.png create mode 100644 app/src/main/res/drawable-mdpi/ic_skip_previous_white_36dp.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_pause_white_36dp.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_pause_white_48dp.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_play_arrow_white_36dp.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_play_arrow_white_48dp.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_skip_next_white_36dp.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_skip_previous_white_36dp.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_pause_white_36dp.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_pause_white_48dp.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_play_arrow_white_36dp.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_play_arrow_white_48dp.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_skip_next_white_36dp.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_skip_previous_white_36dp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_pause_white_36dp.png delete mode 100755 app/src/main/res/drawable-xxxhdpi/ic_pause_white_48dp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_36dp.png delete mode 100755 app/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_48dp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_skip_next_white_36dp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_skip_previous_white_36dp.png delete mode 100644 app/src/main/res/layout-v21/notification_playing.xml delete mode 100644 app/src/main/res/layout-v21/notification_playing_expanded.xml delete mode 100644 app/src/main/res/layout/notification_playing.xml delete mode 100644 app/src/main/res/layout/notification_playing_expanded.xml diff --git a/app/src/main/java/com/kabouzeid/gramophone/helper/MediaSessionHelper.java b/app/src/main/java/com/kabouzeid/gramophone/helper/MediaSessionHelper.java new file mode 100644 index 00000000..373a0ef3 --- /dev/null +++ b/app/src/main/java/com/kabouzeid/gramophone/helper/MediaSessionHelper.java @@ -0,0 +1,70 @@ +package com.kabouzeid.gramophone.helper; + +import android.media.RemoteControlClient; +import android.os.Build; +import android.support.v4.media.session.MediaSessionCompat; +import android.support.v4.media.session.PlaybackStateCompat; + +public class MediaSessionHelper { + + public static void applyState(MediaSessionCompat session, PlaybackStateCompat playbackState) { + session.setPlaybackState(playbackState); + ensureTransportControls(session, playbackState); + } + + private static void ensureTransportControls(MediaSessionCompat session, PlaybackStateCompat playbackState) { + long actions = playbackState.getActions(); + Object rccObj = session.getRemoteControlClient(); + + if (actions != 0 + && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH + && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP + && rccObj != null) { + + int transportControls = 0; + + if ((actions & PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS) != 0) { + transportControls |= RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS; + } + + if ((actions & PlaybackStateCompat.ACTION_REWIND) != 0) { + transportControls |= RemoteControlClient.FLAG_KEY_MEDIA_REWIND; + } + + if ((actions & PlaybackStateCompat.ACTION_PLAY) != 0) { + transportControls |= RemoteControlClient.FLAG_KEY_MEDIA_PLAY; + } + + if ((actions & PlaybackStateCompat.ACTION_PLAY_PAUSE) != 0) { + transportControls |= RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE; + } + + if ((actions & PlaybackStateCompat.ACTION_PAUSE) != 0) { + transportControls |= RemoteControlClient.FLAG_KEY_MEDIA_PAUSE; + } + + if ((actions & PlaybackStateCompat.ACTION_STOP) != 0) { + transportControls |= RemoteControlClient.FLAG_KEY_MEDIA_STOP; + } + + if ((actions & PlaybackStateCompat.ACTION_FAST_FORWARD) != 0) { + transportControls |= RemoteControlClient.FLAG_KEY_MEDIA_FAST_FORWARD; + } + + if ((actions & PlaybackStateCompat.ACTION_SKIP_TO_NEXT) != 0) { + transportControls |= RemoteControlClient.FLAG_KEY_MEDIA_NEXT; + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + if ((actions & PlaybackStateCompat.ACTION_SEEK_TO) != 0) { + transportControls |= RemoteControlClient.FLAG_KEY_MEDIA_POSITION_UPDATE; + } + + if ((actions & PlaybackStateCompat.ACTION_SET_RATING) != 0) { + transportControls |= RemoteControlClient.FLAG_KEY_MEDIA_RATING; + } + } + ((RemoteControlClient) rccObj).setTransportControlFlags(transportControls); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/kabouzeid/gramophone/helper/PlayingNotificationHelper.java b/app/src/main/java/com/kabouzeid/gramophone/helper/PlayingNotificationHelper.java index 99a5e777..a84aa05e 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/helper/PlayingNotificationHelper.java +++ b/app/src/main/java/com/kabouzeid/gramophone/helper/PlayingNotificationHelper.java @@ -5,16 +5,15 @@ package com.kabouzeid.gramophone.helper; */ import android.app.Notification; -import android.app.NotificationManager; import android.app.PendingIntent; import android.app.TaskStackBuilder; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.support.v4.media.session.MediaSessionCompat; import android.support.v7.app.NotificationCompat; -import android.view.View; -import android.widget.RemoteViews; import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.model.Song; @@ -22,192 +21,101 @@ import com.kabouzeid.gramophone.service.MusicService; import com.kabouzeid.gramophone.ui.activities.MusicControllerActivity; import com.kabouzeid.gramophone.util.MusicUtil; import com.nostra13.universalimageloader.core.ImageLoader; -import com.nostra13.universalimageloader.core.assist.FailReason; -import com.nostra13.universalimageloader.core.assist.ImageSize; -import com.nostra13.universalimageloader.core.assist.ViewScaleType; -import com.nostra13.universalimageloader.core.imageaware.NonViewAware; -import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener; public class PlayingNotificationHelper { public static final String TAG = PlayingNotificationHelper.class.getSimpleName(); - public static final int NOTIFICATION_ID = 1337; - private final MusicService service; + public static Notification buildNotification(final Context context, MediaSessionCompat.Token sessionToken, final Song song, final boolean isPlaying) { - private final NotificationManager notificationManager; - private Notification notification = null; + NotificationCompat.MediaStyle style = new NotificationCompat.MediaStyle() + .setMediaSession(sessionToken) + .setShowActionsInCompactView(0, 1, 2); - private RemoteViews notificationLayout; - private RemoteViews notificationLayoutExpanded; + style.setShowCancelButton(true); + style.setCancelButtonIntent(retrievePlaybackAction(context, 3)); - private Song currentSong; - private String currentAlbumArtUri; + Bitmap albumArt = ImageLoader.getInstance().loadImageSync(MusicUtil.getAlbumArtUri(song.albumId).toString()); + if (albumArt == null) { + albumArt = BitmapFactory.decodeResource(context.getResources(), R.drawable.default_album_art); + } - public PlayingNotificationHelper(final MusicService service) { - this.service = service; - notificationManager = (NotificationManager) service - .getSystemService(Context.NOTIFICATION_SERVICE); - } - - public void buildNotification(final Song song, final boolean isPlaying) { - currentSong = song; - notificationLayout = new RemoteViews(service.getPackageName(), - R.layout.notification_playing); - notificationLayoutExpanded = new RemoteViews(service.getPackageName(), - R.layout.notification_playing_expanded); - - notification = new NotificationCompat.Builder(service) + return new NotificationCompat.Builder(context) .setSmallIcon(R.drawable.ic_notification) - .setContentIntent(getOpenMusicControllerPendingIntent()) - .setCategory(NotificationCompat.CATEGORY_PROGRESS) - .setPriority(NotificationCompat.PRIORITY_MAX) + .setLargeIcon(albumArt) + .setContentIntent(getOpenMusicControllerPendingIntent(context)) + .setContentTitle(song.title) + .setContentText(song.artistName) + .setSubText(song.albumName) + .setWhen(0) + .setShowWhen(false) + .setStyle(style) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) - .setContent(notificationLayout) - .setStyle(new NotificationCompat.MediaStyle()) + + .addAction(R.drawable.ic_skip_previous_white_36dp, + "", + retrievePlaybackAction(context, 2)) + + .addAction(isPlaying ? R.drawable.ic_pause_white_36dp : R.drawable.ic_play_arrow_white_36dp, + "", + retrievePlaybackAction(context, 0)) + + .addAction(R.drawable.ic_skip_next_white_36dp, + "", + retrievePlaybackAction(context, 1)) + + .setOnlyAlertOnce(true) .build(); - notification.bigContentView = notificationLayoutExpanded; - - setUpCollapsedLayout(); - setUpExpandedLayout(); - loadAlbumArt(); - setUpPlaybackActions(isPlaying); - setUpExpandedPlaybackActions(isPlaying); - - service.startForeground(NOTIFICATION_ID, notification); } - private PendingIntent getOpenMusicControllerPendingIntent() { - Intent result = new Intent(service, MusicControllerActivity.class); - TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(service); + private static PendingIntent getOpenMusicControllerPendingIntent(final Context context) { + Intent result = new Intent(context, MusicControllerActivity.class); + TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(context); taskStackBuilder.addParentStack(MusicControllerActivity.class); taskStackBuilder.addNextIntent(result); return taskStackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); } - private void setUpExpandedPlaybackActions(boolean isPlaying) { - notificationLayoutExpanded.setOnClickPendingIntent(R.id.button_toggle_play_pause, - retrievePlaybackActions(1)); - - notificationLayoutExpanded.setOnClickPendingIntent(R.id.button_next, - retrievePlaybackActions(2)); - - notificationLayoutExpanded.setOnClickPendingIntent(R.id.button_prev, - retrievePlaybackActions(3)); - - notificationLayoutExpanded.setOnClickPendingIntent(R.id.button_quit, - retrievePlaybackActions(4)); - - notificationLayoutExpanded.setImageViewResource(R.id.button_toggle_play_pause, - isPlaying ? R.drawable.ic_pause_white_48dp : R.drawable.ic_play_arrow_white_48dp); - } - - private void setUpPlaybackActions(boolean isPlaying) { - notificationLayout.setOnClickPendingIntent(R.id.button_toggle_play_pause, - retrievePlaybackActions(1)); - - notificationLayout.setOnClickPendingIntent(R.id.button_next, - retrievePlaybackActions(2)); - - notificationLayout.setOnClickPendingIntent(R.id.button_quit, - retrievePlaybackActions(4)); - - notificationLayout.setImageViewResource(R.id.button_toggle_play_pause, - isPlaying ? R.drawable.ic_pause_white_48dp : R.drawable.ic_play_arrow_white_48dp); - } - - private PendingIntent retrievePlaybackActions(final int which) { - Intent action; - PendingIntent pendingIntent; - final ComponentName serviceName = new ComponentName(service, MusicService.class); + private static PendingIntent retrievePlaybackAction(final Context context, final int which) { + String actionString = null; switch (which) { - case 1: - action = new Intent(MusicService.ACTION_TOGGLE_PLAYBACK); - action.setComponent(serviceName); - pendingIntent = PendingIntent.getService(service, 1, action, 0); - return pendingIntent; - case 2: - action = new Intent(MusicService.ACTION_SKIP); - action.setComponent(serviceName); - pendingIntent = PendingIntent.getService(service, 2, action, 0); - return pendingIntent; - case 3: - action = new Intent(MusicService.ACTION_REWIND); - action.setComponent(serviceName); - pendingIntent = PendingIntent.getService(service, 3, action, 0); - return pendingIntent; - case 4: - action = new Intent(MusicService.ACTION_QUIT); - action.setComponent(serviceName); - pendingIntent = PendingIntent.getService(service, 4, action, 0); - return pendingIntent; - default: + case 0: + actionString = MusicService.ACTION_TOGGLE_PLAYBACK; break; + case 1: + actionString = MusicService.ACTION_SKIP; + break; + case 2: + actionString = MusicService.ACTION_REWIND; + break; + case 3: + actionString = MusicService.ACTION_QUIT; + break; + } + if (actionString != null) { + final ComponentName serviceName = new ComponentName(context, MusicService.class); + Intent actionIntent = new Intent(actionString); + actionIntent.setComponent(serviceName); + return PendingIntent.getService(context, 0, actionIntent, 0); } return null; } - private void setUpCollapsedLayout() { - if (currentSong != null) { - notificationLayout.setTextViewText(R.id.song_title, currentSong.title); - notificationLayout.setTextViewText(R.id.song_artist, currentSong.artistName); - } - } - - private void setUpExpandedLayout() { - if (currentSong != null) { - notificationLayoutExpanded.setTextViewText(R.id.song_title, currentSong.title); - notificationLayoutExpanded.setTextViewText(R.id.song_artist, currentSong.artistName); - notificationLayoutExpanded.setTextViewText(R.id.album_title, currentSong.albumName); - } - } - - private void loadAlbumArt() { - currentAlbumArtUri = MusicUtil.getAlbumArtUri(currentSong.albumId).toString(); - ImageLoader.getInstance().displayImage(currentAlbumArtUri, new NonViewAware(new ImageSize(-1, -1), ViewScaleType.CROP), new SimpleImageLoadingListener() { - @Override - public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { - if (currentAlbumArtUri.equals(imageUri)) - // copy() prevents the original bitmap in the memory cache from being recycled by the remote views - setAlbumArt(loadedImage.copy(loadedImage.getConfig(), true)); - } - - @Override - public void onLoadingFailed(String imageUri, View view, FailReason failReason) { - if (currentAlbumArtUri.equals(imageUri)) - setAlbumArt(null); - } - }); - } - - private void setAlbumArt(Bitmap albumArt) { - if (albumArt != null) { - notificationLayout.setImageViewBitmap(R.id.album_art, albumArt); - notificationLayoutExpanded.setImageViewBitmap(R.id.album_art, albumArt); - } else { - notificationLayout.setImageViewResource(R.id.album_art, R.drawable.default_album_art); - notificationLayoutExpanded.setImageViewResource(R.id.album_art, R.drawable.default_album_art); - } - notificationManager.notify(NOTIFICATION_ID, notification); - } - - public void killNotification() { - service.stopForeground(true); - notification = null; - } - - public void updatePlayState(final boolean isPlaying) { - if (notification == null || notificationManager == null) { - return; - } - if (notificationLayout != null) { - notificationLayout.setImageViewResource(R.id.button_toggle_play_pause, - isPlaying ? R.drawable.ic_pause_white_48dp : R.drawable.ic_play_arrow_white_48dp); - } - if (notificationLayoutExpanded != null) { - notificationLayoutExpanded.setImageViewResource(R.id.button_toggle_play_pause, - isPlaying ? R.drawable.ic_pause_white_48dp : R.drawable.ic_play_arrow_white_48dp); - } - notificationManager.notify(NOTIFICATION_ID, notification); - } +// private void loadAlbumArt() { +// currentAlbumArtUri = MusicUtil.getAlbumArtUri(currentSong.albumId).toString(); +// ImageLoader.getInstance().displayImage(currentAlbumArtUri, new NonViewAware(new ImageSize(-1, -1), ViewScaleType.CROP), new SimpleImageLoadingListener() { +// @Override +// public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { +// if (currentAlbumArtUri.equals(imageUri)) +// // copy() prevents the original bitmap in the memory cache from being recycled by the remote views +// setAlbumArt(loadedImage.copy(loadedImage.getConfig(), true)); +// } +// +// @Override +// public void onLoadingFailed(String imageUri, View view, FailReason failReason) { +// if (currentAlbumArtUri.equals(imageUri)) +// setAlbumArt(null); +// } +// }); +// } } diff --git a/app/src/main/java/com/kabouzeid/gramophone/service/MusicService.java b/app/src/main/java/com/kabouzeid/gramophone/service/MusicService.java index 86cdf726..5a964b58 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/service/MusicService.java +++ b/app/src/main/java/com/kabouzeid/gramophone/service/MusicService.java @@ -1,5 +1,7 @@ package com.kabouzeid.gramophone.service; +import android.app.Notification; +import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.BroadcastReceiver; @@ -10,10 +12,8 @@ import android.content.Intent; import android.content.IntentFilter; import android.graphics.Bitmap; import android.media.AudioManager; -import android.media.MediaMetadata; import android.media.MediaPlayer; import android.media.audiofx.AudioEffect; -import android.media.session.PlaybackState; import android.net.Uri; import android.os.Binder; import android.os.Handler; @@ -33,6 +33,7 @@ import android.widget.Toast; import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.appwidget.MusicPlayerWidget; +import com.kabouzeid.gramophone.helper.MediaSessionHelper; import com.kabouzeid.gramophone.helper.PlayingNotificationHelper; import com.kabouzeid.gramophone.helper.ShuffleHelper; import com.kabouzeid.gramophone.misc.AppKeys; @@ -56,6 +57,8 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe public static final String PHONOGRAPH_PACKAGE_NAME = "com.kabouzeid.gramophone"; public static final String MUSIC_PACKAGE_NAME = "com.android.music"; + public static final int NOTIFICATION_ID = 1337; + public static final String ACTION_TOGGLE_PLAYBACK = "com.kabouzeid.gramophone.action.TOGGLE_PLAYBACK"; public static final String ACTION_PLAY = "com.kabouzeid.gramophone.action.PLAY"; public static final String ACTION_RESUME = "com.kabouzeid.gramophone.action.RESUME"; @@ -69,7 +72,7 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe public static final String PLAYSTATE_CHANGED = "com.kabouzeid.gramophone.playstatechanged"; public static final String REPEATMODE_CHANGED = "com.kabouzeid.gramophone.repeatmodechanged"; public static final String SHUFFLEMODE_CHANGED = "com.kabouzeid.gramophone.shufflemodechanged"; - public static final String POSITION_CHANGED = "com.kabouzeid.phonograph.positionchanged"; + public static final String POSITION_IN_SONG_CHANGED = "com.kabouzeid.phonograph.positionchanged"; private static final int FOCUSCHANGE = 5; private static final int DUCK = 6; @@ -97,14 +100,14 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe private boolean thingsRegistered; private boolean saveQueuesAgain; private boolean isSavingQueues; - private PlayingNotificationHelper playingNotificationHelper; private AudioManager audioManager; - private MediaSessionCompat mSession; + private MediaSessionCompat mediaSession; private PowerManager.WakeLock wakeLock; private String currentAlbumArtUri; private MusicPlayerHandler playerHandler; private boolean fadingDown = false; private HandlerThread handlerThread; + private NotificationManager notificationManager; private final BroadcastReceiver becomingNoisyReceiver = new BroadcastReceiver() { @Override @@ -129,7 +132,6 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe isPlayerPrepared = false; playingQueue = new ArrayList<>(); originalPlayingQueue = new ArrayList<>(); - playingNotificationHelper = new PlayingNotificationHelper(this); shuffleMode = PreferenceManager.getDefaultSharedPreferences(this).getInt(AppKeys.SP_SHUFFLE_MODE, 0); repeatMode = PreferenceManager.getDefaultSharedPreferences(this).getInt(AppKeys.SP_REPEAT_MODE, 0); @@ -143,18 +145,16 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe handlerThread.start(); playerHandler = new MusicPlayerHandler(this, handlerThread.getLooper()); - registerEverything(); + notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); setUpMediaSession(); + + registerEverything(); } private void setUpMediaSession() { - Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); - mediaButtonIntent.setComponent(new ComponentName(getApplicationContext(), MediaButtonIntentReceiver.class)); - PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, 0); - - mSession = new MediaSessionCompat(this, "Phonograph", new ComponentName(getApplicationContext(), MediaButtonIntentReceiver.class), mediaPendingIntent); - mSession.setCallback(new MediaSessionCompat.Callback() { + mediaSession = new MediaSessionCompat(this, "Phonograph", new ComponentName(getApplicationContext(), MediaButtonIntentReceiver.class), getMediaButtonIntent()); + mediaSession.setCallback(new MediaSessionCompat.Callback() { @Override public void onPause() { pausePlaying(false); @@ -186,7 +186,8 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe stopPlaying(); } }); - mSession.setFlags(MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); + mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | + MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); } private void registerEverything() { @@ -205,17 +206,10 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe return audioManager; } - private void initRemoteControlClient() { -// Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); -// mediaButtonIntent.setComponent(new ComponentName(getApplicationContext(), MediaButtonIntentReceiver.class)); -// PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, 0); -// remoteControlClient = new RemoteControlClient(mediaPendingIntent); -// remoteControlClient.setTransportControlFlags( -// RemoteControlClient.FLAG_KEY_MEDIA_PLAY | -// RemoteControlClient.FLAG_KEY_MEDIA_PAUSE | -// RemoteControlClient.FLAG_KEY_MEDIA_NEXT | -// RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS); -// getAudioManager().registerRemoteControlClient(remoteControlClient); + private PendingIntent getMediaButtonIntent() { + Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); + mediaButtonIntent.setComponent(new ComponentName(getApplicationContext(), MediaButtonIntentReceiver.class)); + return PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, 0); } @Override @@ -292,7 +286,7 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe private void killEverythingAndReleaseResources() { stopPlaying(); - playingNotificationHelper.killNotification(); + stopForeground(true); savePosition(); saveQueues(); stopSelf(); @@ -306,8 +300,8 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe player.release(); player = null; } - mSession.setActive(false); - mSession.release(); + mediaSession.setActive(false); + mediaSession.release(); notifyChange(PLAYSTATE_CHANGED); } @@ -383,13 +377,8 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe player.setAudioStreamType(AudioManager.STREAM_MUSIC); player.setDataSource(getApplicationContext(), trackUri); player.prepareAsync(); - } catch (Exception e) { - player.reset(); - player = null; - notifyChange(PLAYSTATE_CHANGED); - - Toast.makeText(getApplicationContext(), getResources().getString(R.string.unplayable_file), Toast.LENGTH_SHORT).show(); - return; + } catch (Exception ignored) { + // handled in onError() } currentSongId = playingQueue.get(getPosition()).id; notifyChange(META_CHANGED); @@ -426,24 +415,26 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe final Song song = playingQueue.get(getPosition()); int playState = isPlaying() - ? PlaybackState.STATE_PLAYING - : PlaybackState.STATE_PAUSED; + ? PlaybackStateCompat.STATE_PLAYING + : PlaybackStateCompat.STATE_PAUSED; - if (what.equals(PLAYSTATE_CHANGED) || what.equals(POSITION_CHANGED)) { - mSession.setPlaybackState(new PlaybackStateCompat.Builder() - .setState(playState, getSongProgressMillis(), 1.0f).build()); + if (what.equals(PLAYSTATE_CHANGED) || what.equals(POSITION_IN_SONG_CHANGED)) { + MediaSessionHelper.applyState(mediaSession, new PlaybackStateCompat.Builder() + .setActions(getAvailablePlaybackStateActions()) + .setState(playState, player != null ? getSongProgressMillis() : 0, 1.0f).build()); } else if (what.equals(META_CHANGED)) { - mSession.setMetadata(new MediaMetadataCompat.Builder() - .putString(MediaMetadata.METADATA_KEY_ARTIST, song.artistName) - .putString(MediaMetadata.METADATA_KEY_ALBUM, song.albumName) - .putString(MediaMetadata.METADATA_KEY_TITLE, song.title) - .putLong(MediaMetadata.METADATA_KEY_DURATION, song.duration) - .putLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER, getPosition() + 1) - .putLong(MediaMetadata.METADATA_KEY_NUM_TRACKS, getPlayingQueue().size()) + mediaSession.setMetadata(new MediaMetadataCompat.Builder() + .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, song.artistName) + .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, song.albumName) + .putString(MediaMetadataCompat.METADATA_KEY_TITLE, song.title) + .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, song.duration) + .putLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER, getPosition() + 1) + .putLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS, getPlayingQueue().size()) .build()); - mSession.setPlaybackState(new PlaybackStateCompat.Builder() - .setState(playState, getSongProgressMillis(), 1.0f).build()); + MediaSessionHelper.applyState(mediaSession, new PlaybackStateCompat.Builder() + .setActions(getAvailablePlaybackStateActions()) + .setState(playState, player != null ? getSongProgressMillis() : 0, 1.0f).build()); } currentAlbumArtUri = MusicUtil.getAlbumArtUri(song.albumId).toString(); @@ -474,14 +465,34 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe } private void updateMediaSessionBitmap(final Bitmap albumArt) { - MediaMetadataCompat current = mSession.getController().getMetadata(); + MediaMetadataCompat current = mediaSession.getController().getMetadata(); if (current == null) current = new MediaMetadataCompat.Builder().build(); - mSession.setMetadata(new MediaMetadataCompat.Builder(current) - .putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, albumArt) + mediaSession.setMetadata(new MediaMetadataCompat.Builder(current) + .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArt) .build()); } + private long getAvailablePlaybackStateActions() { + if (getPlayingQueue() == null || getPlayingQueue().isEmpty()) { + return 0; + } + + long actions = PlaybackStateCompat.ACTION_PLAY_PAUSE; + if (isPlaying()) { + actions |= PlaybackStateCompat.ACTION_PAUSE; + } else { + actions |= PlaybackStateCompat.ACTION_PLAY; + } + if (getPosition() > 0) { + actions |= PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS; + } + if (getPosition() < getPlayingQueue().size() - 1) { + actions |= PlaybackStateCompat.ACTION_SKIP_TO_NEXT; + } + return actions; + } + private void setUpMediaPlayerIfNeeded() { if (player == null) { player = new MediaPlayer(); @@ -496,7 +507,14 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe } private void updateNotification() { - playingNotificationHelper.buildNotification(playingQueue.get(position), isPlaying()); + final boolean isPlaying = isPlaying(); + Notification notification = PlayingNotificationHelper.buildNotification(this, mediaSession.getSessionToken(), getPlayingQueue().get(getPosition()), isPlaying); + if (isPlaying) + startForeground(NOTIFICATION_ID, notification); + else { + notificationManager.notify(NOTIFICATION_ID, notification); + stopForeground(false); + } } private void updateWidgets() { @@ -568,6 +586,7 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe player.reset(); player = null; notifyChange(PLAYSTATE_CHANGED); + Toast.makeText(getApplicationContext(), getResources().getString(R.string.unplayable_file), Toast.LENGTH_SHORT).show(); return false; } @@ -723,7 +742,7 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe } public void resumePlaying(boolean forceNoFading) { - mSession.setActive(true); + mediaSession.setActive(true); if (!forceNoFading && PreferenceUtils.getInstance(this).fadePlayPauseAndInterruptions()) { playerHandler.removeMessages(FADEDOWNANDPAUSE); playerHandler.sendEmptyMessage(FADEUPANDRESUME); @@ -805,6 +824,7 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe public void seekTo(int millis) { player.seekTo(millis); + notifyChange(POSITION_IN_SONG_CHANGED); } public boolean isPlayerPrepared() { @@ -864,7 +884,7 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe private void notifyChange(final String what) { updateMediaSession(what); - if (what.equals(POSITION_CHANGED)) { + if (what.equals(POSITION_IN_SONG_CHANGED)) { return; } @@ -887,7 +907,7 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe if (what.equals(PLAYSTATE_CHANGED)) { final boolean isPlaying = isPlaying(); - playingNotificationHelper.updatePlayState(isPlaying); + updateNotification(); MusicPlayerWidget.updateWidgetsPlayState(this, isPlaying); } else if (what.equals(META_CHANGED)) { updateNotification(); @@ -962,7 +982,7 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe service.fadingDown = true; service.notifyChange(PLAYSTATE_CHANGED); } - currentPlayPauseFadeVolume -= .1f; + currentPlayPauseFadeVolume -= .2f; if (currentPlayPauseFadeVolume > 0f) { sendEmptyMessageDelayed(FADEDOWNANDPAUSE, 10); } else { @@ -980,7 +1000,7 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe service.notifyChange(PLAYSTATE_CHANGED); } service.resume(); - currentPlayPauseFadeVolume += .1f; + currentPlayPauseFadeVolume += .2f; if (currentPlayPauseFadeVolume < 1.0f) { sendEmptyMessageDelayed(FADEUPANDRESUME, 10); } else { diff --git a/app/src/main/res/drawable-hdpi/ic_pause_white_36dp.png b/app/src/main/res/drawable-hdpi/ic_pause_white_36dp.png new file mode 100644 index 0000000000000000000000000000000000000000..ea4357b9f42c5386a1813baf4eed56f9365ff429 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0y~yU@!w=4mJh`h91|fy9^8rsh%#5Ar-gY-rUH^puppL zu;-OV-?Oxfr>?oVJY`zX8}nD$`0;Tj9te0-6(PCR_34B8xf^D^Ud{f$p%FXS%lf;_ gZBs@QRQ9ZukE5fYE4#fm0|Nttr>mdKI;Vst0Ah?fi2wiq literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_pause_white_48dp.png b/app/src/main/res/drawable-hdpi/ic_pause_white_48dp.png deleted file mode 100644 index 72dfa9fa6ca284c97ddf67b8f79d895c7415017e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 215 zcmeAS@N?(olHy`uVBq!ia0y~yVDJE84i*LmhW}5h&oD4BC?tCX`7$t6sWC7#v@kII zVqjosc)`F>YQVtoDuIE)Y6b&?c)^@qfi?^b3`|Mh?k)`f+xyS#XJBC9EbxddW?~)y}6P1kbwYe zKzG+PMu|q*LqdsMH<*?+XeM-=Il%IzBtYgr*LIOk+4z0`JnI|OUBAm(&x}m+5%MuO z$RZ3PqE+6stdU5xW8Re9^0Q_l_olSwrNWnf@n@O1TaS?83{1OQ7zctHRF literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_play_arrow_white_48dp.png b/app/src/main/res/drawable-hdpi/ic_play_arrow_white_48dp.png deleted file mode 100644 index 043acd808ec133c8353be75d77ce9afeea456c9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 399 zcmeAS@N?(olHy`uVBq!ia0y~yVDJE84i*LmhW}5h&oD4BC?tCX`7$t6sWC7#v@kII zVqjosc)`F>YQVtoDuIE)Y6b&?c)^@qfi?^b3`|Mh?k)`f+xyS#XJBC9EbxddW?x*=`5*@DvM`jx{d$O|_6efi+9XvIado>?N z!m_6;S(=VGoOfqu*>J&7tC7KNwb2Hq#89>}g~di2SS6=4ny%QvW8>hO`hZzWgW3MV zIinA(Z#9_n1Ii??Fr-d(lnro`yuzHT(>!Z|Z)!nCz@uZ4&nJ8Sy`n9?&T8ZQjLMg5 z`sVFE_i94ax}f9zzKr%S1kIEml&*7>Wc~)y}6O|kb?y4 zgUKRhVbivSHGP{VwyQz<1&dYVOb7J~oO2E^Cgta5r>84(%zNK>oyA-D#ADlv+)4b0 zp1$+%Fl0N*c9_Tbi~*GRZJg7PCTbfJ_iBlsM1FWd| zIlar^S?{|G+oW`!HuZ@lo)L~+tZN!^iu0}Jp&8az;VnyLF7zq&>|B)WD)ISOoN{pU z(m%KIy$*1hO2i-Sy|r3nXT_VV)2dJMZ@DwAYxaYwx721FpSJLpWAW;;3r{itmIf;mI^5yK7R$`SZ+wZWp${ zxn`zdr^k|w9R`OulzX5=QCn$1&ev}K2q)g@8(5P3@2#+kO84%s%UC4y%;vnKVSos)WXes<|QPUZkhC5og;!@_UY!2Qelq8 zC(Z61x|N}S^SE`yrt{K^yKBtj4xX{o?^itYbg@KswaDeI7yOjZ?0J_im6%n(;H~b} zAmuYTP3^bL4u0F1x>zucZwpVQqOSK==GcYhPc)I$ztaD0e0swnNjuij^ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_pause_white_36dp.png b/app/src/main/res/drawable-mdpi/ic_pause_white_36dp.png new file mode 100644 index 0000000000000000000000000000000000000000..418c664cf307d80342eac2dfc4e7a20c5645f08c GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0y~yU{C>J4mJh`hKCF@W-u@?xO%!chE&{odwnA(g98V% zgZuxprA*!I+!KW_E!|<{mUe6zi-5odp$pkYSO2q>nqOsSf`MIpQRbiiraCyJJFxzX Xl)2~-_|}Gjfq}u()z4*}Q$iB}D%d3Z literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_pause_white_48dp.png b/app/src/main/res/drawable-mdpi/ic_pause_white_48dp.png deleted file mode 100644 index 14b6d17d4a46396d02905e9886265f2beaee6b65..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 193 zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4i*LmhQHi~JPZsB3dtTpz6=aiY77hwEes65 z7#J8DUNA6}8Za=tN?>5Hn!&&zUNC1@pbY~915=W>y9>kr_Wm>b85kHi3p^r=85p>Q zL70(Y)*J~21_nz{7srr@!*8z{axo|fFgt$!@19*h_dy}YgTe~DWM4fJG3!u diff --git a/app/src/main/res/drawable-mdpi/ic_play_arrow_white_36dp.png b/app/src/main/res/drawable-mdpi/ic_play_arrow_white_36dp.png new file mode 100644 index 0000000000000000000000000000000000000000..fbdf1da0d53d0e31b78d79b0b2cef314f6890706 GIT binary patch literal 231 zcmeAS@N?(olHy`uVBq!ia0y~yU{C>J4mJh`hKCF@W-u@?tn+kn45_%4{Nw+B`@;!` zcoy?Xm0noU%(k$(hi!KAKZZhcfnr`U_Jap(70P6N_?jAzI_Mb9kYQn3-)K>0V9CK& z#f(s9?s%fq6vwBut7F0TW-(qd_Peq= zfoxt^Vw+V1n>X!!n4l@q&F+2BB4ZU_z*8yX2(9a`%}akemV_;H7oN6cjm;yepNs!) i3S{rK%J8t}V9>NbXFL7PL16|41_n=8KbLh*2~7YNa8ZW< literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_play_arrow_white_48dp.png b/app/src/main/res/drawable-mdpi/ic_play_arrow_white_48dp.png deleted file mode 100644 index a55d19922f71c313b6613fd661d95a4ad6c2738a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 318 zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4i*LmhQHi~JPZsB3dtTpz6=aiY77hwEes65 z7#J8DUNA6}8Za=tN?>5Hn!&&zUNC1@pbY~915=W>y9>kr_Wm>b85kHi3p^r=85p>Q zL70(Y)*J~228L~(E{-7)hu>b?$lGin;P&wNh9!&IITKnZC>|0@VKZX1osy>~eM9Wo zbeWfX4yfPsf1b_rHdChHK%-QHx$JHs13tDiA9jW{HaDg)u&B8;@iE-U_^H8YkXGd< z%dp|{Mh(UWRr7nR8Fqe*V>f!N%WU*Wmvz#|dyFoR_p)~!`K{jYG37$+#4i(>l_%?6 zo;q!PUdWd{C5xS`-Yj`+C6w|tKF#RFrLC%xDJLII6;0W?dhz=Ad=>%rADH<$`WPRn T>)c>qU|{fc^>bP0l+XkKjb&|$ diff --git a/app/src/main/res/drawable-mdpi/ic_skip_next_white_36dp.png b/app/src/main/res/drawable-mdpi/ic_skip_next_white_36dp.png new file mode 100644 index 0000000000000000000000000000000000000000..893cf2c640ee5445067071b38813abe6698490fd GIT binary patch literal 216 zcmeAS@N?(olHy`uVBq!ia0y~yU{C>J4mJh`hKCF@W-u@?%=dJ045_&FcG^bXLk1$O zcb68A?jdc0=ObNuZ0R)O8}MSfFQSj@@8 V){ips7#J8BJYD@<);T3K0RRICR7n5; literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_skip_previous_white_36dp.png b/app/src/main/res/drawable-mdpi/ic_skip_previous_white_36dp.png new file mode 100644 index 0000000000000000000000000000000000000000..b5395b6afd06520a8f1c372345272d6e5d74a9d5 GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0y~yU{C>J4mJh`hKCF@W-u@?Z1Qw*45_%4{Nw+B`@;!` zcoy?Xm0noU>?UjCBGbZiVq=GV$8=sX_M6Nfos+&^y5zXV;SS@Gde4jA+U%JOA8-Dj zk>DURh4sk&f6446r4u9s@_+WrUpVV%=kVu~eWF7#dm-b;FaM7)&$2op(UJd0o%g~O zM>mI>S_4ZCvDC|KlbaK6RBupuuVT@3d#^Rm{0B iGiFy^afCYT!~ur+Z%$rHxHB8%6$VdNKbLh*2~7Z&=3r$2 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_pause_white_36dp.png b/app/src/main/res/drawable-xhdpi/ic_pause_white_36dp.png new file mode 100644 index 0000000000000000000000000000000000000000..500cb7bf1def152610fd1beff4b09d02bee3a355 GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0y~yVDJE84mJh`hS0a0-5D4d>O5T>Ln>~)y}gi^!GVLt z@mKz@6%USDGdXV(GyJFJ`BIj}p@D&siG@Qz0ZcA9?Xchct-S(VlxRju7Xya?M4t*o dQ${TBujXRGJ<{427#J8BJYD@<);T3K0RUp>DTM$4 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_pause_white_48dp.png b/app/src/main/res/drawable-xhdpi/ic_pause_white_48dp.png deleted file mode 100644 index dd4bfdba5459117c0a954614cdab5177f1b40602..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 256 zcmeAS@N?(olHy`uVBq!ia0y~yU`POA4i*Lm29JsRH#0CWC?tCX`7$t6sWC7#v@kII zVqjosc)`F>YQVtoDuIE)Y6b&?c)^@qfi?^b3`|Mh?k)`f+xyS#XJBC9EbxddW?vd$@?2>{j7IvM}~ diff --git a/app/src/main/res/drawable-xhdpi/ic_play_arrow_white_36dp.png b/app/src/main/res/drawable-xhdpi/ic_play_arrow_white_36dp.png new file mode 100644 index 0000000000000000000000000000000000000000..1eb926d22cdb8f3a0838e95457eb0618a27b47aa GIT binary patch literal 367 zcmeAS@N?(olHy`uVBq!ia0y~yVDJE84mJh`hS0a0-5D4d%{*NkLn>~)y|t0|kbyw! z!wUgM48kpvGnzCLxMwhJOW-U^V6KXiI4o*cA6*&P0 zCJu!LFu~!#z{n!tz)<@l*!-0Rjbi`fv0w3 z`T|d_#_|PkrY;a$kTZ3G+5(-a3)~hgnYtisLCREy1(Nnj>2ii~m+II5RL-`G6N&D6 z^dT_$d|>lot@+kV!p!H#q<_0;_w&`dm)rfLx!nF9PrP>Z?D}*){WGtBoqn?VHn)KI z3a39@aTl+yYQVtoDuIE)Y6b&?c)^@qfi?^b3`|Mh?k)`f+xyS#XJBC9EbxddW?;mkSN+-?eId@8naAJ&12XY~bw}ZYwLB3&3LYI=#LZCg;jp(PgK@fAS}enX zZd?CU2Avp-PghwP_E;8#voYLR{b&~J0W8!)=i`Sz+n^nPdooU079oHBq zJ&NM?=*Tuzuvurzu(0qgGe=Lhy+c4uHIvh$ThbdW*C{iY9WCWK(6*zGIiu&bN5irm zeQXi3*FQ37KhAPEr2gf!=Xc>r|2osv&h3({-SFJMe2PWURaw;~?UpYKt5Oa2F6Fs< z#hj&B#v$3@I71G{GY*EAi(OwHzB?h|8?#4z0Snt^b_J6eR~tSgTw_|Izia7yDHXQO zObUPRsM*fg+0c~mjIpa}ChLUyvYVBX2@Q;F5=ex@<6rDSt#Sf)&)B|VU|?YIboFyt I=akR{0P;+(@&Et; diff --git a/app/src/main/res/drawable-xhdpi/ic_skip_next_white_36dp.png b/app/src/main/res/drawable-xhdpi/ic_skip_next_white_36dp.png new file mode 100644 index 0000000000000000000000000000000000000000..fa85f1899bdd207d76bd6d2f40832431f3be2815 GIT binary patch literal 368 zcmeAS@N?(olHy`uVBq!ia0y~yVDJE84mJh`hS0a0-5D4d%{^TlLn>~)y=AD!k|@Id zq1R>MCC#m?mz6V`7clu9;N8JsUeHv^z_;L9&?^(E&Yta^PKNhq&+X*>RQLbM{rcbD zX=(Ro&n%5Kzg(usz{J8Kpy1HJpa~)vnOHa`tmAy4w(Bpq{i3P%>|4$he-Q|%yU_n4 zwM00e?n3(uxdnd~22&oA;iRK8oh zyW!Iww|++6^iwwBTp6cq!uc}Z*n|sZoUsX)%9vWY&gQ}e8}=94+zxNO-yBiBw$JnY z-6g-}Ka0zK{#*IU{o;zmh`*i-tY7ziJM`wvp*4Gp?rtx7dw%NDz1Qs)H;To{_|0B? zs(z0_yz#mHfB&RjwOl20;fCcZkqQ1Ew8WU;eqn-n@8$M7rrv+*E}LDw`xzJ*7(8A5 KT-G@yGywoFo}9J- literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_skip_previous_white_36dp.png b/app/src/main/res/drawable-xhdpi/ic_skip_previous_white_36dp.png new file mode 100644 index 0000000000000000000000000000000000000000..d5347eec546c1deef5d1d2091390122e1aa3b029 GIT binary patch literal 373 zcmeAS@N?(olHy`uVBq!ia0y~yVDJE84mJh`hS0a0-5D4dZ9H8ZLn>~)y=BkG7%0$C zI5ES-N_Fk5dCUb&ejEG_a9-oIU{o()WDmHkRjSqMa?E6s?wXrV->Ut-XMQqVfB%vB zH)~A=R|ZxoFt7+XFff7$K`710A|T2##VmFI%4yq}Ulc39ee`M9J_ge*Q@@qe#>zKT z-P*X~b(n0%y1U(b@mb+g3s=g^^a9ARQDGd-eXk#uF=qA%cYRq&vfF(;wH9Jo7@>$Cj50$wo9t< zwEjJ_|L4r@(x2Q7Z?D?OdLr-CrmX7^%iOm~r*Y@axcPOfu){as-=+>_$#TCxJh%`k z*gwy5&x1EVyw7}`Uh`YV;h5cV#dAhXj0z15OdKGh14?r!G-zDpE}pEO*!Vn3j)8%J N!PC{xWt~$(69BQamMH)L literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_pause_white_36dp.png b/app/src/main/res/drawable-xxhdpi/ic_pause_white_36dp.png new file mode 100644 index 0000000000000000000000000000000000000000..60798c7638e1f76d06d3d706f6ec3206e34e6577 GIT binary patch literal 285 zcmeAS@N?(olHy`uVBq!ia0y~yV8{Vs4mJh`hW@nhvkVLjPdr^5Ln>~)y?c?D!GOiV zaq;b#=@YhmQF$MKhhfnwr{W@(1SYkF11vrV8aQV(FbW$mGOHypvH2We;hE8pDG_0| zwRHaT1G~~*+Z||NWM<=$Fi4;q<3@c#5Hn!&&zUNC1@pbY~915=W>y9>kr_Wm>b85kHi3p^r=85p>Q zL70(Y)*J~228J7+E{-7;x87bj$jP9-TWZ@7{aA;s) zWKsc>ATA>lh;(RR-~>sfG0g4zbWFVdQ&MBb@0Cpfnq5uE@ diff --git a/app/src/main/res/drawable-xxhdpi/ic_play_arrow_white_36dp.png b/app/src/main/res/drawable-xxhdpi/ic_play_arrow_white_36dp.png new file mode 100644 index 0000000000000000000000000000000000000000..ad5a0ef5066ed0a5c61b12a0396a7e79112d63c1 GIT binary patch literal 490 zcmeAS@N?(olHy`uVBq!ia0y~yV8{Vs4mJh`hW@nhvkVN38$DedLn>~)y=&;pk|@IR z!287t!v>ZQ4cq~YS_fE{GYNVyFkdNAIbDC$YKL~(z3-C@H^djsyqWZVL+)+IqDP7h z!U;?~GZ=&u4zSE%U{*W8B4NO&cA$aNfRW9o!Bg>u?F^j_`=@T7n(ZK&@Vj=sjl(I% z+wXT2F>ABGDY4h~KTvew+wX{-tkamwcHN&keX4c>NSWUphLZ`mk8n=lGs|Pz($G7T zAvfWx@B+a#RZJ$$p?(cz8+LITu&zmC@?ly%gF*PudjIB-af zVZ#Pa2Av#2T(Ac3`qkuvN~?dlY@L1^A5`%hoQ8swUaT+8r`7|)11nx6MhRLU&%AZwo*!1$! S(NG2k1_n=8KbLh*2~7Y`&cmAk literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_play_arrow_white_48dp.png b/app/src/main/res/drawable-xxhdpi/ic_play_arrow_white_48dp.png deleted file mode 100644 index de7f9bdb5b6080e7e47bf9203e44008d60bbfbe2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 666 zcmeAS@N?(olHy`uVBq!ia0y~yV3+{H94rhB48Hza#taM$3dtTpz6=aiY77hwEes65 z7#J8DUNA6}8Za=tN?>5Hn!&&zUNC1@pbY~915=W>y9>kr_Wm>b85kHi3p^r=85p>Q zL70(Y)*J~21|}g-7srr_TW{}dEIs5P;Cj)2qlHpC*8da&he=;9gvB##ZCv6i{`M<(0Jq1adADA&1xR~L%8Ps? z&$>kCV?VQ((Eo@9EFb&XHudjko>2P7wxQ?od*&3WdVPh%KXx2nuA%X7W`onC`Meobe?Bw%_SO3>==^w|+eGu< z%*JI$?5!_+`0<=wO6I?m1M}l}){KZh+KjxN^`;BneO%9e#qytNqt&tfS^?XCgtNU8 z`hUwo_7VRD`~64GSrv4CRQ|jCjC`rm=eN>F*Y4XHm?LZY?bnkP2NO%{E@U&8a#W=% z$n8AGQRTa!&knPkURRb~Sk1u8UB#;qx1fu=s%*hS$MZZUsxK-VD<IJ(QZ?fLy?oiFw zc38t1!)U~}i&~)y<=#^;waJf zP&brmqK}5ES~;V60h8YW-W?3)1x$Pg7>@)w&2(Ah)%z|%>Es)q^7DVb{ak(T&YR$+ z*U}?PW48y**~4*w#pgf+=ZpqMVFN~HwFD+Mp93sBGa5K03>bwC5}4Ey4zRq*|Gx5W zg8romzqcp+yceu~;8DZV-=24uY->Eq@cO-KDTfYU#J=@cST|TC{Iy;7t>Gx+>F*P* zSjE`a?B9KbZ-Yg`&$!^@U`>9pOSd(EG+A!t2WdKgMG~ZG>pkU0(H+yORW>+X&+2Ch z`;qm2;sLFgv$jGJM^|rjXIfpe^t(qw@472;oNFFVy`kJ_x^HE*%7&SFZ{#?0j!AEJ zXNo?s7DS%ly{p`)`=ag5!~NBY z-|#@*->Ref292Wo+RwSO9ID}XUUO`{Od$;PCc4jE%l$>@)e;Kw%0E^v_BRxWZlfg8nHviBxIDHhu;M1_n=8 KKbLh*2~7YLs^$#< literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_skip_previous_white_36dp.png b/app/src/main/res/drawable-xxhdpi/ic_skip_previous_white_36dp.png new file mode 100644 index 0000000000000000000000000000000000000000..fbb27ab3ca4783736e323f93a42c763471729396 GIT binary patch literal 552 zcmeAS@N?(olHy`uVBq!ia0y~yV8{Vs4mJh`hW@nhvkVN3?>$`{Ln>~)y<@1y5-4;0 zW3S8Ni<+5NzsNKQ7clu9;Iv>=f54*mfFUbtso&BGCq7GcvSg>FKim8L`R7Ub_SW-L zHvhhT@?4OY@zImM3~C8XY(58AcxE(kN*FK-8zeBPB^+S!Incm4qk&P_fRR}(A^vrd z(%l1B@0f0oc>7GwJKlK1Ki%i&it|m^Nk;59D=s%(FB$Q@uULQUddVB_*FMdQ+L@N{ z`Sy9+ttDp(E_&dw4hm@`pU zAcA#+qP4f3%~ zhP>6fhNHhD>K`Q6?$JN@dY{GdIm`TffM?G>}@lN2?>8wS1~X!FnGH9xvX4A0#j?OL41_uu2 zgJ15Kym7p6UFMDboXOiJZu`l?sM5ePfngGZkOPwkgC_&00;5U;SV+hLECdojQDa;F z_YFITLIVTS2}TB{6Lk#?OdJXgG7Jh0P+_nfHiAm(LB?P+9xR5%Js|ZkVX#}V5lHSw zRqw&%0S*+DFyK^}uK)@*co=~~sexqz%LH&ZX0cs9eJ0>M^D$2b1_lOCS3j3^P60w}CP)PO&@?~JCQe$9fXklRZ z#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7?_g0-CY>|xA&jf&%nUIS>O>_%)r1c z48n{Iv*t)JFfi(Px;TbZ+4o j)yPexVkF;|WHY~WVXZGt4SvADz`)??>gTe~DWM4frrAaR diff --git a/app/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_36dp.png b/app/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_36dp.png new file mode 100644 index 0000000000000000000000000000000000000000..4ee72e525406833db0dcc869165d8ffab43a5fca GIT binary patch literal 651 zcmeAS@N?(olHy`uVBq!ia0y~yV3+{H9Bd2>4A0#j?O` zi%$;;GHNjJu5e)8!65p8Nx0$wWBIxmj>*nECCetge0e=|KI5lV)9TB)^-gb!S&~u5 z!Q{cfslcehsM5ePfngGZkOPwkgC|(10W1U(Kv5&Lr~lg8cFuq;U+bdIuhr%kUBI#6 ztzGnYIUR>Uhu43%#YJD2GjI@exLvzd&L*W{QNy+0*?YI=+2k}RHEjExXIu4v!Id#L z{S)&R?g=OPFXTC>**nBC%>2XfmM!HI^Od(gbq%}boa7IfZv2z+RxL>K+!OYU?=$~^ z)Xe2S@r3=v6ZQ-qho|cHAg#@@D^K!+3_4)`7c8Z5(%14QqtQ=BuZqh)bqzjs4U^(u zL6o>m&-=uj@`>5xBde3X|m*JSu0w}CP)PO&@?~JCQe$9fXklRZ z#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7?_g0-CY>|xA&jf&%nUIS>O>_%)r1c z48n{Iv*t)JFfi@*ba4!+xb^n##!wkY0oRMS5+=6t3+iZcurhjfNGLRYRTWO3+B_#d zw6>n>`<$8P$tCgcQcuP*Ffb%AFi0>kurV|+63a9be6UvTHJifr>c1f5OD~- z`u);CF}1WB zbGe3v2X`_j6cpq!6fCV2NT@0BV~Y@+Q_MJx<+)FT>p@GwgwO&%<_PgQn;FE|p35{W zJ!r|CP*~u{5FtC~F5@-!^!x_qrp@{X6c64Meeib5gEw3SKgdc;-{gO@&%0(PpVyp` R#=yY9;OXk;vd$@?2>{tB86*Gz diff --git a/app/src/main/res/drawable-xxxhdpi/ic_skip_next_white_36dp.png b/app/src/main/res/drawable-xxxhdpi/ic_skip_next_white_36dp.png new file mode 100644 index 0000000000000000000000000000000000000000..a84f34228bc66221901979b215beb8633f63d820 GIT binary patch literal 749 zcmeAS@N?(olHy`uVBq!ia0y~yV3+{H9Bd2>4A0#j?Ovxj|E7mR7=CK7FZ@6~jGQ%sG3zw>; z9GV%TvizAd6db(YWHRt_WXuPNG2Oa8kL|*PhDFs<4h*f|Od1%t-exi|irl))z{H`@ z@a_AbPyP}P#rr$eCI_u(T`2+xIgQ?IQ)slArrY=xY<{#9m^&mXgG8Fcq0GqMC^9B1NKaG{S? zz+s^*_kx3ruH`xnY^+cG?=VhDI?e=kWds8+Q^rbJ?gi%DX@$X)0i1Y1 m$p<8GLJ+JLIT20SUS7F=uF7gNtN9EJ3=E#GelF{r5}E*a^%J!K literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_skip_previous_white_36dp.png b/app/src/main/res/drawable-xxxhdpi/ic_skip_previous_white_36dp.png new file mode 100644 index 0000000000000000000000000000000000000000..d2e06a9235134f9148fa64ab2176437284075ecb GIT binary patch literal 728 zcmeAS@N?(olHy`uVBq!ia0y~yV3+{H9Bd2>4A0#j?OHpPwyU3+Lbmk6Ojm8Y+yzkbe|@%8Nzx#dsg8`#)NW>w8k z;&)(X`gM0>kqrYc+l%*otO5=TWw{j^oUFwh7+TA88W_0VMldjn+}g;%q_HKLktHDG zI1|T$3w^8?9yBbn7IR=`KD9BK(L`av9BVO$X2w%{lNn7o7VIq3X<%b8dEUnw@Vw#K zy^Rd7L@ul<(`m3`*>XyjdqE$=)EgTaUaIE#J!SKXjru0V-F+8f*04VjZzs>d{|d>y_QLz z{91;AwRj=V0-f-v^=jc!j9g^~J45&bHq5twy_1<^LB`fMnGB{}E2i129cG=Jt5#SZ^2S~!Hh&t%|b%2;R1yWk+h z(|ea0qyz%a+43%EWPEz#GJ}*%K#4yy$ASy<*aRFF+VUziI8{qIFtmO%0R>woDA+E8 pf^9h{*q{n0{5nZV!kGDsE&24^gkq)h_6!UR44$rjF6*2UngA)63M2pk literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout-v21/notification_playing.xml b/app/src/main/res/layout-v21/notification_playing.xml deleted file mode 100644 index 2baa5969..00000000 --- a/app/src/main/res/layout-v21/notification_playing.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout-v21/notification_playing_expanded.xml b/app/src/main/res/layout-v21/notification_playing_expanded.xml deleted file mode 100644 index ba3172c2..00000000 --- a/app/src/main/res/layout-v21/notification_playing_expanded.xml +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/notification_playing.xml b/app/src/main/res/layout/notification_playing.xml deleted file mode 100644 index c7f21c1b..00000000 --- a/app/src/main/res/layout/notification_playing.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/notification_playing_expanded.xml b/app/src/main/res/layout/notification_playing_expanded.xml deleted file mode 100644 index 263e5102..00000000 --- a/app/src/main/res/layout/notification_playing_expanded.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -