diff --git a/src/ch/blinkenlights/android/vanilla/MediaUtils.java b/src/ch/blinkenlights/android/vanilla/MediaUtils.java index 05359da0..a9b0f291 100644 --- a/src/ch/blinkenlights/android/vanilla/MediaUtils.java +++ b/src/ch/blinkenlights/android/vanilla/MediaUtils.java @@ -408,13 +408,15 @@ public class MediaUtils { } /** - * Returns a song randomly selected from all the songs in the Android - * MediaStore. + * Returns a list of songs randomly selected from all the songs in the Android + * MediaStore. When albumShuffle is specified, the returned list may contain all the songs + * for that album, in order. Otherwise, only one song will be returned. If no songs are + * available, the list will be empty. * * @param context The Context to use * @param albumShuffle Whether or not we should shuffle by album */ - public static Song getRandomSong(Context context, boolean albumShuffle) { + public static List getRandomSongs(Context context, boolean albumShuffle) { ArrayList songs = sAllSongs; if (songs.size() == 0 || sAllSongsAS != albumShuffle) { @@ -426,12 +428,31 @@ public class MediaUtils { sSongCount = songs.size(); } - Song result = null; + final List results = new ArrayList<>(); + if (songs.size() > 0) { - result = songs.remove(0); - result.flags |= Song.FLAG_RANDOM; + + long firstAlbumId = songs.get(0).albumId; + + // if we're in album shuffle mode, we'll want to add in the entire album in one go, + // so loop through the upcoming songs and add all those that have the same album id + // as the song we initially got + boolean addMore; + do { + final Song song = songs.remove(0); + + // when in album shuffle mode, we don't want to flag any of the added songs + // as random, since manually enqueuing or changing random mode will remove every album track. + if (!albumShuffle) { + song.flags |= Song.FLAG_RANDOM; + } + + results.add(song); + addMore = albumShuffle && songs.size() > 0 && songs.get(0).albumId == firstAlbumId; + } while (addMore); } - return result; + + return results; } /** @@ -605,5 +626,4 @@ public class MediaUtils { return TYPE_INVALID; } } - } diff --git a/src/ch/blinkenlights/android/vanilla/SongTimeline.java b/src/ch/blinkenlights/android/vanilla/SongTimeline.java index 3a0fd78d..4006401f 100644 --- a/src/ch/blinkenlights/android/vanilla/SongTimeline.java +++ b/src/ch/blinkenlights/android/vanilla/SongTimeline.java @@ -36,7 +36,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; +import java.util.List; import java.util.ListIterator; + import junit.framework.Assert; /** @@ -580,10 +582,18 @@ public final class SongTimeline { return null; } else if (pos == size) { if (mFinishAction == FINISH_RANDOM) { - song = MediaUtils.getRandomSong(mContext, mShuffleMode == SHUFFLE_ALBUMS); - if (song == null) + + final List songs = MediaUtils.getRandomSongs(mContext, mShuffleMode == SHUFFLE_ALBUMS); + if (songs.size() == 0) { return null; - timeline.add(song); + } + + for (Song newSong : songs) { + timeline.add(newSong); + } + + song = songs.get(0); + mLastRandomSong = song; // Keep the queue at 20 items to avoid growing forever // Note that we do not broadcast the addition of this song, as it