diff --git a/src/ch/blinkenlights/android/vanilla/MediaUtils.java b/src/ch/blinkenlights/android/vanilla/MediaUtils.java index 9a6398f8..05359da0 100644 --- a/src/ch/blinkenlights/android/vanilla/MediaUtils.java +++ b/src/ch/blinkenlights/android/vanilla/MediaUtils.java @@ -120,10 +120,13 @@ public class MediaUtils { private static Random sRandom; /** - * Shuffled list of all ids in the library. + * Shuffled list of all songs in the library. */ - private static long[] sAllSongs; - private static int sAllSongsIdx; + private static ArrayList sAllSongs = new ArrayList(); + /** + * True if sAllSongs was shuffled by album. + */ + private static boolean sAllSongsAS; /** * Total number of songs in the music library, or -1 for uninitialized. @@ -256,22 +259,6 @@ public class MediaUtils { return 0; } - /** - * Shuffle an array using Fisher-Yates algorithm. - * - * @param list The array. It will be shuffled in place. - */ - public static void shuffle(long[] list) - { - Random random = getRandom(); - for (int i = list.length; --i != -1; ) { - int j = random.nextInt(i + 1); - long tmp = list[j]; - list[j] = list[i]; - list[i] = tmp; - } - } - /** * Shuffle a Song list using Collections.shuffle(). * @@ -338,32 +325,26 @@ public class MediaUtils { } /** - * Returns a shuffled array contaning the ids of all the songs on the + * Returns a list containing all the songs found on the * device's library. * * @param context The Context to use */ - private static long[] queryAllSongs(Context context) { - QueryTask query = new QueryTask(MediaLibrary.TABLE_SONGS, Song.EMPTY_PROJECTION, null, null, null); + private static ArrayList getAllSongs(Context context) { + QueryTask query = new QueryTask(MediaLibrary.VIEW_SONGS_ALBUMS_ARTISTS, Song.FILLED_PROJECTION, null, null, null); Cursor cursor = query.runQuery(context); - if (cursor == null || cursor.getCount() == 0) { - sSongCount = 0; - return null; - } + ArrayList list = new ArrayList(); - int count = cursor.getCount(); - long[] ids = new long[count]; - for (int i = 0; i != count; ++i) { - if (!cursor.moveToNext()) - return null; - ids[i] = cursor.getLong(0); + if (cursor == null) + return list; + + while (cursor.moveToNext()) { + Song song = new Song(-1); + song.populate(cursor); + list.add(song); } - sSongCount = count; cursor.close(); - - shuffle(ids); - - return ids; + return list; } /** @@ -373,7 +354,7 @@ public class MediaUtils { public static void onMediaChange() { sSongCount = -1; - sAllSongs = null; + sAllSongs.clear(); } /** @@ -431,25 +412,25 @@ public class MediaUtils { * MediaStore. * * @param context The Context to use + * @param albumShuffle Whether or not we should shuffle by album */ - public static Song getRandomSong(Context context) - { - long[] songs = sAllSongs; + public static Song getRandomSong(Context context, boolean albumShuffle) { + ArrayList songs = sAllSongs; - if (songs == null) { - songs = queryAllSongs(context); - if (songs == null) - return null; - sAllSongs = songs; - sAllSongsIdx = 0; - } else if (sAllSongsIdx == sAllSongs.length) { - sAllSongsIdx = 0; - shuffle(sAllSongs); + if (songs.size() == 0 || sAllSongsAS != albumShuffle) { + sAllSongs = getAllSongs(context); + sAllSongsAS = albumShuffle; + shuffle(sAllSongs, albumShuffle); + songs = sAllSongs; + // We don't need it but know the value, we can fill the cache for free. + sSongCount = songs.size(); } - Song result = getSongByTypeId(context, MediaUtils.TYPE_SONG, sAllSongs[sAllSongsIdx]); - result.flags |= Song.FLAG_RANDOM; - sAllSongsIdx++; + Song result = null; + if (songs.size() > 0) { + result = songs.remove(0); + result.flags |= Song.FLAG_RANDOM; + } return result; } diff --git a/src/ch/blinkenlights/android/vanilla/SongTimeline.java b/src/ch/blinkenlights/android/vanilla/SongTimeline.java index a5778cba..3a0fd78d 100644 --- a/src/ch/blinkenlights/android/vanilla/SongTimeline.java +++ b/src/ch/blinkenlights/android/vanilla/SongTimeline.java @@ -580,7 +580,7 @@ public final class SongTimeline { return null; } else if (pos == size) { if (mFinishAction == FINISH_RANDOM) { - song = MediaUtils.getRandomSong(mContext); + song = MediaUtils.getRandomSong(mContext, mShuffleMode == SHUFFLE_ALBUMS); if (song == null) return null; timeline.add(song);