From f504e83cbf731f07041119477a85214b3ff76862 Mon Sep 17 00:00:00 2001 From: Adrian Campos Date: Tue, 4 Apr 2017 09:07:15 -0700 Subject: [PATCH 1/3] Fixes issue 111. Instead of calling play() when the playlist is empty, show a toast --- .../java/com/kabouzeid/gramophone/service/MusicService.java | 6 ++++-- app/src/main/res/values/strings.xml | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) 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 a5bd9076..83efdc80 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/service/MusicService.java +++ b/app/src/main/java/com/kabouzeid/gramophone/service/MusicService.java @@ -298,7 +298,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP break; case ACTION_PLAY: ArrayList songs = intent.getParcelableArrayListExtra(INTENT_EXTRA_SONGS); - if (songs != null) { + if (songs != null && !songs.isEmpty()) { int shuffleMode = intent.getIntExtra(INTENT_EXTRA_SHUFFLE_MODE, getShuffleMode()); if (intent.hasExtra(INTENT_EXTRA_SHUFFLE_MODE) && intent.getIntExtra(INTENT_EXTRA_SHUFFLE_MODE, 0) == SHUFFLE_MODE_SHUFFLE) { int startPosition = 0; @@ -310,8 +310,10 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP } else { openQueue(songs, 0, false); } + play(); + } else { + Toast.makeText(getApplicationContext(), R.string.no_songs_in_playlist, Toast.LENGTH_LONG).show(); } - play(); break; case ACTION_REWIND: back(true); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6eef7d46..e3d2be94 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -288,4 +288,6 @@ @string/last_added @string/last_added + + No songs in playlist From 54414e7d3ee70c35a3023b0c3b2e2b329a15912c Mon Sep 17 00:00:00 2001 From: Adrian Campos Date: Wed, 5 Apr 2017 16:39:22 -0700 Subject: [PATCH 2/3] Fixes issue #112 - Crash on too many songs in App Shortcut playlist Instead of passing all songs in an intent extra, pass the Playlist which is then used to load the songs in MusicService --- .../AppShortcutLauncherActivity.java | 27 +++++----- .../smartplaylist/ShuffleAllPlaylist.java | 54 +++++++++++++++++++ .../gramophone/service/MusicService.java | 54 +++++++++++++++---- app/src/main/res/values/strings.xml | 1 + 4 files changed, 111 insertions(+), 25 deletions(-) create mode 100644 app/src/main/java/com/kabouzeid/gramophone/model/smartplaylist/ShuffleAllPlaylist.java diff --git a/app/src/main/java/com/kabouzeid/gramophone/appshortcuts/AppShortcutLauncherActivity.java b/app/src/main/java/com/kabouzeid/gramophone/appshortcuts/AppShortcutLauncherActivity.java index b6b72cc8..51f19deb 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/appshortcuts/AppShortcutLauncherActivity.java +++ b/app/src/main/java/com/kabouzeid/gramophone/appshortcuts/AppShortcutLauncherActivity.java @@ -8,15 +8,14 @@ import android.support.annotation.IntDef; import com.kabouzeid.gramophone.appshortcuts.shortcuttype.LastAddedShortcutType; import com.kabouzeid.gramophone.appshortcuts.shortcuttype.ShuffleAllShortcutType; import com.kabouzeid.gramophone.appshortcuts.shortcuttype.TopTracksShortcutType; -import com.kabouzeid.gramophone.loader.LastAddedLoader; -import com.kabouzeid.gramophone.loader.SongLoader; -import com.kabouzeid.gramophone.loader.TopAndRecentlyPlayedTracksLoader; -import com.kabouzeid.gramophone.model.Song; +import com.kabouzeid.gramophone.model.Playlist; +import com.kabouzeid.gramophone.model.smartplaylist.LastAddedPlaylist; +import com.kabouzeid.gramophone.model.smartplaylist.MyTopTracksPlaylist; +import com.kabouzeid.gramophone.model.smartplaylist.ShuffleAllPlaylist; import com.kabouzeid.gramophone.service.MusicService; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; /** * @author Adrian Campos @@ -46,18 +45,18 @@ public class AppShortcutLauncherActivity extends Activity { switch (shortcutType) { case SHORTCUT_TYPE_SHUFFLE_ALL: - startServiceWithSongs(MusicService.SHUFFLE_MODE_SHUFFLE, - SongLoader.getAllSongs(getApplicationContext())); + startServiceWithPlaylist(MusicService.SHUFFLE_MODE_SHUFFLE, + new ShuffleAllPlaylist(getApplicationContext())); DynamicShortcutManager.reportShortcutUsed(this, ShuffleAllShortcutType.getId()); break; case SHORTCUT_TYPE_TOP_TRACKS: - startServiceWithSongs(MusicService.SHUFFLE_MODE_NONE, - TopAndRecentlyPlayedTracksLoader.getTopTracks(getApplicationContext())); + startServiceWithPlaylist(MusicService.SHUFFLE_MODE_NONE, + new MyTopTracksPlaylist(getApplicationContext())); DynamicShortcutManager.reportShortcutUsed(this, TopTracksShortcutType.getId()); break; case SHORTCUT_TYPE_LAST_ADDED: - startServiceWithSongs(MusicService.SHUFFLE_MODE_NONE, - LastAddedLoader.getLastAddedSongs(getApplicationContext())); + startServiceWithPlaylist(MusicService.SHUFFLE_MODE_NONE, + new LastAddedPlaylist(getApplicationContext())); DynamicShortcutManager.reportShortcutUsed(this, LastAddedShortcutType.getId()); break; } @@ -65,12 +64,12 @@ public class AppShortcutLauncherActivity extends Activity { finish(); } - private void startServiceWithSongs(int shuffleMode, ArrayList songs) { + private void startServiceWithPlaylist(int shuffleMode, Playlist playlist) { Intent intent = new Intent(this, MusicService.class); - intent.setAction(MusicService.ACTION_PLAY); + intent.setAction(MusicService.ACTION_PLAY_PLAYLIST); Bundle bundle = new Bundle(); - bundle.putParcelableArrayList(MusicService.INTENT_EXTRA_SONGS, songs); + bundle.putParcelable(MusicService.INTENT_EXTRA_PLAYLIST, playlist); bundle.putInt(MusicService.INTENT_EXTRA_SHUFFLE_MODE, shuffleMode); intent.putExtras(bundle); diff --git a/app/src/main/java/com/kabouzeid/gramophone/model/smartplaylist/ShuffleAllPlaylist.java b/app/src/main/java/com/kabouzeid/gramophone/model/smartplaylist/ShuffleAllPlaylist.java new file mode 100644 index 00000000..d9fc3013 --- /dev/null +++ b/app/src/main/java/com/kabouzeid/gramophone/model/smartplaylist/ShuffleAllPlaylist.java @@ -0,0 +1,54 @@ +package com.kabouzeid.gramophone.model.smartplaylist; + +import android.content.Context; +import android.os.Parcel; +import android.support.annotation.NonNull; + +import com.kabouzeid.gramophone.R; +import com.kabouzeid.gramophone.loader.SongLoader; +import com.kabouzeid.gramophone.model.Song; + +import java.util.ArrayList; + +public class ShuffleAllPlaylist extends AbsSmartPlaylist { + + public ShuffleAllPlaylist(@NonNull Context context) { + super(context.getString(R.string.shuffle_all), R.drawable.ic_shuffle_white_24dp); + } + + @NonNull + @Override + public ArrayList getSongs(@NonNull Context context) { + return SongLoader.getAllSongs(context); + } + + @Override + public void clear(@NonNull Context context) { + //Can't clear all songs. Don't do anything here? + } + + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + } + + protected ShuffleAllPlaylist(Parcel in) { + super(in); + } + + public static final Creator CREATOR = new Creator() { + public ShuffleAllPlaylist createFromParcel(Parcel source) { + return new ShuffleAllPlaylist(source); + } + + public ShuffleAllPlaylist[] newArray(int size) { + return new ShuffleAllPlaylist[size]; + } + }; +} 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 83efdc80..fda4539b 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/service/MusicService.java +++ b/app/src/main/java/com/kabouzeid/gramophone/service/MusicService.java @@ -46,7 +46,10 @@ import com.kabouzeid.gramophone.glide.BlurTransformation; import com.kabouzeid.gramophone.glide.SongGlideRequest; import com.kabouzeid.gramophone.helper.ShuffleHelper; import com.kabouzeid.gramophone.helper.StopWatch; +import com.kabouzeid.gramophone.loader.PlaylistSongLoader; +import com.kabouzeid.gramophone.model.Playlist; import com.kabouzeid.gramophone.model.Song; +import com.kabouzeid.gramophone.model.smartplaylist.AbsSmartPlaylist; import com.kabouzeid.gramophone.provider.HistoryStore; import com.kabouzeid.gramophone.provider.MusicPlaybackQueueStore; import com.kabouzeid.gramophone.provider.SongPlayCountStore; @@ -74,12 +77,14 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP public static final String ACTION_TOGGLE_PAUSE = PHONOGRAPH_PACKAGE_NAME + ".togglepause"; public static final String ACTION_PLAY = PHONOGRAPH_PACKAGE_NAME + ".play"; + public static final String ACTION_PLAY_PLAYLIST = PHONOGRAPH_PACKAGE_NAME + ".play.playlist"; public static final String ACTION_PAUSE = PHONOGRAPH_PACKAGE_NAME + ".pause"; public static final String ACTION_STOP = PHONOGRAPH_PACKAGE_NAME + ".stop"; public static final String ACTION_SKIP = PHONOGRAPH_PACKAGE_NAME + ".skip"; public static final String ACTION_REWIND = PHONOGRAPH_PACKAGE_NAME + ".rewind"; public static final String ACTION_QUIT = PHONOGRAPH_PACKAGE_NAME + ".quitservice"; public static final String INTENT_EXTRA_SONGS = PHONOGRAPH_PACKAGE_NAME + ".intentextra.songs"; + public static final String INTENT_EXTRA_PLAYLIST = PHONOGRAPH_PACKAGE_NAME + "intentextra.playlist"; public static final String INTENT_EXTRA_SHUFFLE_MODE = PHONOGRAPH_PACKAGE_NAME + ".intentextra.shufflemode"; public static final String APP_WIDGET_UPDATE = PHONOGRAPH_PACKAGE_NAME + ".appwidgetupdate"; @@ -297,20 +302,29 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP pause(); break; case ACTION_PLAY: + //Load songs from intent ArrayList songs = intent.getParcelableArrayListExtra(INTENT_EXTRA_SONGS); - if (songs != null && !songs.isEmpty()) { - int shuffleMode = intent.getIntExtra(INTENT_EXTRA_SHUFFLE_MODE, getShuffleMode()); - if (intent.hasExtra(INTENT_EXTRA_SHUFFLE_MODE) && intent.getIntExtra(INTENT_EXTRA_SHUFFLE_MODE, 0) == SHUFFLE_MODE_SHUFFLE) { - int startPosition = 0; - if (!songs.isEmpty()) { - startPosition = new Random().nextInt(songs.size()); - } - openQueue(songs, startPosition, false); - setShuffleMode(shuffleMode); + + //Play songs with the intent's shuffle mode, if it has one + playSongs(songs, + intent.getIntExtra(INTENT_EXTRA_SHUFFLE_MODE, getShuffleMode())); + break; + case ACTION_PLAY_PLAYLIST: + //Load playlist from intent + Playlist playlist = intent.getParcelableExtra(INTENT_EXTRA_PLAYLIST); + if (playlist != null) { + //Get songs from playlist + ArrayList playlistSongs; + if (playlist instanceof AbsSmartPlaylist) { + playlistSongs = ((AbsSmartPlaylist) playlist).getSongs(getApplicationContext()); } else { - openQueue(songs, 0, false); + //noinspection unchecked + playlistSongs = (ArrayList) (List) PlaylistSongLoader.getPlaylistSongList(getApplicationContext(), playlist.id); } - play(); + + //Play songs with the intent's shuffle mode, if it has one + playSongs(playlistSongs, + intent.getIntExtra(INTENT_EXTRA_SHUFFLE_MODE, getShuffleMode())); } else { Toast.makeText(getApplicationContext(), R.string.no_songs_in_playlist, Toast.LENGTH_LONG).show(); } @@ -860,6 +874,24 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP } } + public void playSongs(ArrayList songs, int shuffleMode) { + if (songs != null && !songs.isEmpty()) { + if (shuffleMode == SHUFFLE_MODE_SHUFFLE) { + int startPosition = 0; + if (!songs.isEmpty()) { + startPosition = new Random().nextInt(songs.size()); + } + openQueue(songs, startPosition, false); + setShuffleMode(shuffleMode); + } else { + openQueue(songs, 0, false); + } + play(); + } else { + Toast.makeText(getApplicationContext(), R.string.no_songs_in_playlist, Toast.LENGTH_LONG).show(); + } + } + public void playPreviousSong(boolean force) { playSongAt(getPreviousPosition(force)); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e3d2be94..feb01126 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -181,6 +181,7 @@ Favorites Last added History + Shuffle All My top tracks Remove cover Download from Last.fm From 3232370e47e1f37f92e543caf344edd6282cc3ee Mon Sep 17 00:00:00 2001 From: Karim Abou Zeid Date: Sat, 22 Apr 2017 15:34:59 +0200 Subject: [PATCH 3/3] Created CustomPlaylist class, cleaned up some code --- .../gramophone/adapter/PlaylistAdapter.java | 5 ++- ...er.java => CustomPlaylistSongAdapter.java} | 6 +-- .../AppShortcutLauncherActivity.java | 10 ----- .../shortcuttype/BaseShortcutType.java | 4 +- .../helper/menu/PlaylistMenuHelper.java | 6 +-- .../gramophone/model/AbsCustomPlaylist.java | 27 +++++++++++++ .../model/smartplaylist/AbsSmartPlaylist.java | 9 +---- .../smartplaylist/ShuffleAllPlaylist.java | 5 +-- .../gramophone/service/MusicService.java | 39 ++++++++++--------- .../ui/activities/PlaylistDetailActivity.java | 12 +++--- app/src/main/res/values/strings.xml | 3 +- 11 files changed, 70 insertions(+), 56 deletions(-) rename app/src/main/java/com/kabouzeid/gramophone/adapter/song/{SmartPlaylistSongAdapter.java => CustomPlaylistSongAdapter.java} (83%) create mode 100644 app/src/main/java/com/kabouzeid/gramophone/model/AbsCustomPlaylist.java diff --git a/app/src/main/java/com/kabouzeid/gramophone/adapter/PlaylistAdapter.java b/app/src/main/java/com/kabouzeid/gramophone/adapter/PlaylistAdapter.java index ecb9e1b8..868f4448 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/adapter/PlaylistAdapter.java +++ b/app/src/main/java/com/kabouzeid/gramophone/adapter/PlaylistAdapter.java @@ -22,6 +22,7 @@ import com.kabouzeid.gramophone.helper.menu.PlaylistMenuHelper; import com.kabouzeid.gramophone.helper.menu.SongsMenuHelper; import com.kabouzeid.gramophone.interfaces.CabHolder; import com.kabouzeid.gramophone.loader.PlaylistSongLoader; +import com.kabouzeid.gramophone.model.AbsCustomPlaylist; import com.kabouzeid.gramophone.model.Playlist; import com.kabouzeid.gramophone.model.Song; import com.kabouzeid.gramophone.model.smartplaylist.AbsSmartPlaylist; @@ -157,8 +158,8 @@ public class PlaylistAdapter extends AbsMultiSelectAdapter getSongList(@NonNull List playlists) { final ArrayList songs = new ArrayList<>(); for (Playlist playlist : playlists) { - if (playlist instanceof AbsSmartPlaylist) { - songs.addAll(((AbsSmartPlaylist) playlist).getSongs(activity)); + if (playlist instanceof AbsCustomPlaylist) { + songs.addAll(((AbsCustomPlaylist) playlist).getSongs(activity)); } else { songs.addAll(PlaylistSongLoader.getPlaylistSongList(activity, playlist.id)); } diff --git a/app/src/main/java/com/kabouzeid/gramophone/adapter/song/SmartPlaylistSongAdapter.java b/app/src/main/java/com/kabouzeid/gramophone/adapter/song/CustomPlaylistSongAdapter.java similarity index 83% rename from app/src/main/java/com/kabouzeid/gramophone/adapter/song/SmartPlaylistSongAdapter.java rename to app/src/main/java/com/kabouzeid/gramophone/adapter/song/CustomPlaylistSongAdapter.java index 69715276..b6a325ca 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/adapter/song/SmartPlaylistSongAdapter.java +++ b/app/src/main/java/com/kabouzeid/gramophone/adapter/song/CustomPlaylistSongAdapter.java @@ -18,11 +18,11 @@ import java.util.ArrayList; /** * @author Karim Abou Zeid (kabouzeid) */ -public class SmartPlaylistSongAdapter extends SongAdapter { +public class CustomPlaylistSongAdapter extends SongAdapter { - public static final String TAG = SmartPlaylistSongAdapter.class.getSimpleName(); + public static final String TAG = CustomPlaylistSongAdapter.class.getSimpleName(); - public SmartPlaylistSongAdapter(AppCompatActivity activity, @NonNull ArrayList dataSet, @LayoutRes int itemLayoutRes, boolean usePalette, @Nullable CabHolder cabHolder) { + public CustomPlaylistSongAdapter(AppCompatActivity activity, @NonNull ArrayList dataSet, @LayoutRes int itemLayoutRes, boolean usePalette, @Nullable CabHolder cabHolder) { super(activity, dataSet, itemLayoutRes, usePalette, cabHolder); overrideMultiSelectMenuRes(R.menu.menu_cannot_delete_single_songs_playlist_songs_selection); } diff --git a/app/src/main/java/com/kabouzeid/gramophone/appshortcuts/AppShortcutLauncherActivity.java b/app/src/main/java/com/kabouzeid/gramophone/appshortcuts/AppShortcutLauncherActivity.java index 51f19deb..03bbdb79 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/appshortcuts/AppShortcutLauncherActivity.java +++ b/app/src/main/java/com/kabouzeid/gramophone/appshortcuts/AppShortcutLauncherActivity.java @@ -3,7 +3,6 @@ package com.kabouzeid.gramophone.appshortcuts; import android.app.Activity; import android.content.Intent; import android.os.Bundle; -import android.support.annotation.IntDef; import com.kabouzeid.gramophone.appshortcuts.shortcuttype.LastAddedShortcutType; import com.kabouzeid.gramophone.appshortcuts.shortcuttype.ShuffleAllShortcutType; @@ -14,9 +13,6 @@ import com.kabouzeid.gramophone.model.smartplaylist.MyTopTracksPlaylist; import com.kabouzeid.gramophone.model.smartplaylist.ShuffleAllPlaylist; import com.kabouzeid.gramophone.service.MusicService; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - /** * @author Adrian Campos */ @@ -33,7 +29,6 @@ public class AppShortcutLauncherActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - @ShortcutType int shortcutType = SHORTCUT_TYPE_NONE; //Set shortcutType from the intent extras @@ -76,9 +71,4 @@ public class AppShortcutLauncherActivity extends Activity { startService(intent); } - - @Retention(RetentionPolicy.SOURCE) - @IntDef({SHORTCUT_TYPE_SHUFFLE_ALL, SHORTCUT_TYPE_TOP_TRACKS, SHORTCUT_TYPE_LAST_ADDED, SHORTCUT_TYPE_NONE}) - public @interface ShortcutType { - } } diff --git a/app/src/main/java/com/kabouzeid/gramophone/appshortcuts/shortcuttype/BaseShortcutType.java b/app/src/main/java/com/kabouzeid/gramophone/appshortcuts/shortcuttype/BaseShortcutType.java index ca44f21a..53733d9f 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/appshortcuts/shortcuttype/BaseShortcutType.java +++ b/app/src/main/java/com/kabouzeid/gramophone/appshortcuts/shortcuttype/BaseShortcutType.java @@ -26,7 +26,7 @@ public abstract class BaseShortcutType { abstract ShortcutInfo getShortcutInfo(); - static public String getId(){ + static public String getId() { return ID_PREFIX + "invalid"; } @@ -37,7 +37,7 @@ public abstract class BaseShortcutType { * @param shortcutType Describes the type of shortcut to create (ShuffleAll, TopTracks, custom playlist, etc.) * @return */ - Intent getPlaySongsIntent(@AppShortcutLauncherActivity.ShortcutType int shortcutType) { + Intent getPlaySongsIntent(int shortcutType) { Intent intent = new Intent(context, AppShortcutLauncherActivity.class); intent.setAction(Intent.ACTION_VIEW); diff --git a/app/src/main/java/com/kabouzeid/gramophone/helper/menu/PlaylistMenuHelper.java b/app/src/main/java/com/kabouzeid/gramophone/helper/menu/PlaylistMenuHelper.java index 6e37b020..7ef920ea 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/helper/menu/PlaylistMenuHelper.java +++ b/app/src/main/java/com/kabouzeid/gramophone/helper/menu/PlaylistMenuHelper.java @@ -14,9 +14,9 @@ import com.kabouzeid.gramophone.dialogs.DeletePlaylistDialog; import com.kabouzeid.gramophone.dialogs.RenamePlaylistDialog; import com.kabouzeid.gramophone.helper.MusicPlayerRemote; import com.kabouzeid.gramophone.loader.PlaylistSongLoader; +import com.kabouzeid.gramophone.model.AbsCustomPlaylist; import com.kabouzeid.gramophone.model.Playlist; import com.kabouzeid.gramophone.model.Song; -import com.kabouzeid.gramophone.model.smartplaylist.AbsSmartPlaylist; import com.kabouzeid.gramophone.util.PlaylistsUtil; import java.io.IOException; @@ -77,8 +77,8 @@ public class PlaylistMenuHelper { @NonNull private static ArrayList getPlaylistSongs(@NonNull Activity activity, Playlist playlist) { - return playlist instanceof AbsSmartPlaylist ? - ((AbsSmartPlaylist) playlist).getSongs(activity) : + return playlist instanceof AbsCustomPlaylist ? + ((AbsCustomPlaylist) playlist).getSongs(activity) : PlaylistSongLoader.getPlaylistSongList(activity, playlist.id); } } diff --git a/app/src/main/java/com/kabouzeid/gramophone/model/AbsCustomPlaylist.java b/app/src/main/java/com/kabouzeid/gramophone/model/AbsCustomPlaylist.java new file mode 100644 index 00000000..ccc3af4a --- /dev/null +++ b/app/src/main/java/com/kabouzeid/gramophone/model/AbsCustomPlaylist.java @@ -0,0 +1,27 @@ +package com.kabouzeid.gramophone.model; + +import android.content.Context; +import android.os.Parcel; +import android.support.annotation.NonNull; + +import java.util.ArrayList; + +/** + * @author Karim Abou Zeid (kabouzeid) + */ + +public abstract class AbsCustomPlaylist extends Playlist { + public AbsCustomPlaylist(int id, String name) { + super(id, name); + } + + public AbsCustomPlaylist() { + } + + public AbsCustomPlaylist(Parcel in) { + super(in); + } + + @NonNull + public abstract ArrayList getSongs(Context context); +} diff --git a/app/src/main/java/com/kabouzeid/gramophone/model/smartplaylist/AbsSmartPlaylist.java b/app/src/main/java/com/kabouzeid/gramophone/model/smartplaylist/AbsSmartPlaylist.java index 8a89f8c3..d21e39b3 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/model/smartplaylist/AbsSmartPlaylist.java +++ b/app/src/main/java/com/kabouzeid/gramophone/model/smartplaylist/AbsSmartPlaylist.java @@ -6,15 +6,12 @@ import android.support.annotation.DrawableRes; import android.support.annotation.Nullable; import com.kabouzeid.gramophone.R; -import com.kabouzeid.gramophone.model.Playlist; -import com.kabouzeid.gramophone.model.Song; - -import java.util.ArrayList; +import com.kabouzeid.gramophone.model.AbsCustomPlaylist; /** * @author Karim Abou Zeid (kabouzeid) */ -public abstract class AbsSmartPlaylist extends Playlist { +public abstract class AbsSmartPlaylist extends AbsCustomPlaylist { @DrawableRes public final int iconRes; @@ -28,8 +25,6 @@ public abstract class AbsSmartPlaylist extends Playlist { this.iconRes = R.drawable.ic_queue_music_white_24dp; } - public abstract ArrayList getSongs(Context context); - public abstract void clear(Context context); @Override diff --git a/app/src/main/java/com/kabouzeid/gramophone/model/smartplaylist/ShuffleAllPlaylist.java b/app/src/main/java/com/kabouzeid/gramophone/model/smartplaylist/ShuffleAllPlaylist.java index d9fc3013..bf8c818d 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/model/smartplaylist/ShuffleAllPlaylist.java +++ b/app/src/main/java/com/kabouzeid/gramophone/model/smartplaylist/ShuffleAllPlaylist.java @@ -13,7 +13,7 @@ import java.util.ArrayList; public class ShuffleAllPlaylist extends AbsSmartPlaylist { public ShuffleAllPlaylist(@NonNull Context context) { - super(context.getString(R.string.shuffle_all), R.drawable.ic_shuffle_white_24dp); + super(context.getString(R.string.action_shuffle_all), R.drawable.ic_shuffle_white_24dp); } @NonNull @@ -24,10 +24,9 @@ public class ShuffleAllPlaylist extends AbsSmartPlaylist { @Override public void clear(@NonNull Context context) { - //Can't clear all songs. Don't do anything here? + // Shuffle all is not a real "Smart Playlist" } - @Override public int describeContents() { return 0; 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 fda4539b..1b8a5e1f 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/service/MusicService.java +++ b/app/src/main/java/com/kabouzeid/gramophone/service/MusicService.java @@ -47,9 +47,9 @@ import com.kabouzeid.gramophone.glide.SongGlideRequest; import com.kabouzeid.gramophone.helper.ShuffleHelper; import com.kabouzeid.gramophone.helper.StopWatch; import com.kabouzeid.gramophone.loader.PlaylistSongLoader; +import com.kabouzeid.gramophone.model.AbsCustomPlaylist; import com.kabouzeid.gramophone.model.Playlist; import com.kabouzeid.gramophone.model.Song; -import com.kabouzeid.gramophone.model.smartplaylist.AbsSmartPlaylist; import com.kabouzeid.gramophone.provider.HistoryStore; import com.kabouzeid.gramophone.provider.MusicPlaybackQueueStore; import com.kabouzeid.gramophone.provider.SongPlayCountStore; @@ -83,7 +83,6 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP public static final String ACTION_SKIP = PHONOGRAPH_PACKAGE_NAME + ".skip"; public static final String ACTION_REWIND = PHONOGRAPH_PACKAGE_NAME + ".rewind"; public static final String ACTION_QUIT = PHONOGRAPH_PACKAGE_NAME + ".quitservice"; - public static final String INTENT_EXTRA_SONGS = PHONOGRAPH_PACKAGE_NAME + ".intentextra.songs"; public static final String INTENT_EXTRA_PLAYLIST = PHONOGRAPH_PACKAGE_NAME + "intentextra.playlist"; public static final String INTENT_EXTRA_SHUFFLE_MODE = PHONOGRAPH_PACKAGE_NAME + ".intentextra.shufflemode"; @@ -302,31 +301,35 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP pause(); break; case ACTION_PLAY: - //Load songs from intent - ArrayList songs = intent.getParcelableArrayListExtra(INTENT_EXTRA_SONGS); - - //Play songs with the intent's shuffle mode, if it has one - playSongs(songs, - intent.getIntExtra(INTENT_EXTRA_SHUFFLE_MODE, getShuffleMode())); + play(); break; case ACTION_PLAY_PLAYLIST: - //Load playlist from intent Playlist playlist = intent.getParcelableExtra(INTENT_EXTRA_PLAYLIST); + int shuffleMode = intent.getIntExtra(INTENT_EXTRA_SHUFFLE_MODE, getShuffleMode()); if (playlist != null) { - //Get songs from playlist ArrayList playlistSongs; - if (playlist instanceof AbsSmartPlaylist) { - playlistSongs = ((AbsSmartPlaylist) playlist).getSongs(getApplicationContext()); + if (playlist instanceof AbsCustomPlaylist) { + playlistSongs = ((AbsCustomPlaylist) playlist).getSongs(getApplicationContext()); } else { //noinspection unchecked playlistSongs = (ArrayList) (List) PlaylistSongLoader.getPlaylistSongList(getApplicationContext(), playlist.id); } - - //Play songs with the intent's shuffle mode, if it has one - playSongs(playlistSongs, - intent.getIntExtra(INTENT_EXTRA_SHUFFLE_MODE, getShuffleMode())); + if (!playlistSongs.isEmpty()) { + if (shuffleMode == SHUFFLE_MODE_SHUFFLE) { + int startPosition = 0; + if (!playlistSongs.isEmpty()) { + startPosition = new Random().nextInt(playlistSongs.size()); + } + openQueue(playlistSongs, startPosition, true); + setShuffleMode(shuffleMode); + } else { + openQueue(playlistSongs, 0, true); + } + } else { + Toast.makeText(getApplicationContext(), R.string.playlist_is_empty, Toast.LENGTH_LONG).show(); + } } else { - Toast.makeText(getApplicationContext(), R.string.no_songs_in_playlist, Toast.LENGTH_LONG).show(); + Toast.makeText(getApplicationContext(), R.string.playlist_is_empty, Toast.LENGTH_LONG).show(); } break; case ACTION_REWIND: @@ -888,7 +891,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP } play(); } else { - Toast.makeText(getApplicationContext(), R.string.no_songs_in_playlist, Toast.LENGTH_LONG).show(); + Toast.makeText(getApplicationContext(), R.string.playlist_is_empty, Toast.LENGTH_LONG).show(); } } diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/PlaylistDetailActivity.java b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/PlaylistDetailActivity.java index ad403225..21d6ca3d 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/PlaylistDetailActivity.java +++ b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/PlaylistDetailActivity.java @@ -20,8 +20,8 @@ import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropM import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils; import com.kabouzeid.appthemehelper.ThemeStore; import com.kabouzeid.gramophone.R; +import com.kabouzeid.gramophone.adapter.song.CustomPlaylistSongAdapter; import com.kabouzeid.gramophone.adapter.song.PlaylistSongAdapter; -import com.kabouzeid.gramophone.adapter.song.SmartPlaylistSongAdapter; import com.kabouzeid.gramophone.adapter.song.SongAdapter; import com.kabouzeid.gramophone.dialogs.SleepTimerDialog; import com.kabouzeid.gramophone.helper.MusicPlayerRemote; @@ -29,10 +29,10 @@ import com.kabouzeid.gramophone.interfaces.CabHolder; import com.kabouzeid.gramophone.interfaces.LoaderIds; import com.kabouzeid.gramophone.loader.PlaylistSongLoader; import com.kabouzeid.gramophone.misc.WrappedAsyncTaskLoader; +import com.kabouzeid.gramophone.model.AbsCustomPlaylist; import com.kabouzeid.gramophone.model.Playlist; import com.kabouzeid.gramophone.model.PlaylistSong; import com.kabouzeid.gramophone.model.Song; -import com.kabouzeid.gramophone.model.smartplaylist.AbsSmartPlaylist; import com.kabouzeid.gramophone.ui.activities.base.AbsSlidingMusicPanelActivity; import com.kabouzeid.gramophone.util.NavigationUtil; import com.kabouzeid.gramophone.util.PhonographColorUtil; @@ -94,8 +94,8 @@ public class PlaylistDetailActivity extends AbsSlidingMusicPanelActivity impleme private void setUpRecyclerView() { recyclerView.setLayoutManager(new LinearLayoutManager(this)); - if (playlist instanceof AbsSmartPlaylist) { - adapter = new SmartPlaylistSongAdapter(this, new ArrayList(), R.layout.item_list, false, this); + if (playlist instanceof AbsCustomPlaylist) { + adapter = new CustomPlaylistSongAdapter(this, new ArrayList(), R.layout.item_list, false, this); recyclerView.setAdapter(adapter); } else { recyclerViewDragDropManager = new RecyclerViewDragDropManager(); @@ -251,8 +251,8 @@ public class PlaylistDetailActivity extends AbsSlidingMusicPanelActivity impleme @Override public ArrayList loadInBackground() { - if (playlist instanceof AbsSmartPlaylist) { - return ((AbsSmartPlaylist) playlist).getSongs(getContext()); + if (playlist instanceof AbsCustomPlaylist) { + return ((AbsCustomPlaylist) playlist).getSongs(getContext()); } else { //noinspection unchecked return (ArrayList) (List) PlaylistSongLoader.getPlaylistSongList(getContext(), playlist.id); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index feb01126..74a2614c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -181,7 +181,6 @@ Favorites Last added History - Shuffle All My top tracks Remove cover Download from Last.fm @@ -290,5 +289,5 @@ @string/last_added @string/last_added - No songs in playlist + Playlist is empty