From cce040ded8c708596fa34e8a30627c7daa495760 Mon Sep 17 00:00:00 2001 From: Christopher Eby Date: Sat, 17 Sep 2011 21:04:54 -0500 Subject: [PATCH] Query all info for songs chosen from library --- src/org/kreed/vanilla/MediaUtils.java | 39 ++++++++++++++--------- src/org/kreed/vanilla/Song.java | 21 +++++++++++-- src/org/kreed/vanilla/SongSelector.java | 2 +- src/org/kreed/vanilla/SongTimeline.java | 41 +++++++++++++++---------- 4 files changed, 69 insertions(+), 34 deletions(-) diff --git a/src/org/kreed/vanilla/MediaUtils.java b/src/org/kreed/vanilla/MediaUtils.java index 4f440bd3..ed1df8ae 100644 --- a/src/org/kreed/vanilla/MediaUtils.java +++ b/src/org/kreed/vanilla/MediaUtils.java @@ -127,7 +127,7 @@ public class MediaUtils { } /** - * Return an array containing all the song ids that match the specified parameters + * Returns a Cursor queried with the given information. * * @param type Type the id represents. Must be one of the Song.TYPE_* * constants. @@ -136,30 +136,41 @@ public class MediaUtils { * @param selection An extra selection to be passed to the query. May be * null. Must not be used with type == TYPE_SONG or type == TYPE_PLAYLIST */ - public static long[] getAllSongIdsWith(int type, long id, String selection) + public static Cursor query(int type, long id, String[] projection, String selection) { - Cursor cursor; - switch (type) { - case TYPE_SONG: - assert(selection == null); - return new long[] { id }; case TYPE_ARTIST: case TYPE_ALBUM: - cursor = getMediaCursor(type, id, new String[] { MediaStore.Audio.Media._ID }, selection); - break; + case TYPE_SONG: + return getMediaCursor(type, id, projection, selection); case TYPE_PLAYLIST: assert(selection == null); - cursor = getPlaylistCursor(id, new String[] { MediaStore.Audio.Playlists.Members.AUDIO_ID }); - break; + return getPlaylistCursor(id, projection); case TYPE_GENRE: - // NOTE: AUDIO_ID does not seem to work here, strangely. - cursor = queryGenre(id, new String[] { MediaStore.Audio.Genres.Members._ID }, selection, null); - break; + return queryGenre(id, projection, selection, null); default: throw new IllegalArgumentException("Specified type not valid: " + type); } + } + /** + * Return an array containing all the song ids that match the specified parameters + * + * @param type Type the id represents. Must be one of the Song.TYPE_* + * constants. + * @param id The id of the element in the MediaStore content provider for + * the given type. + */ + public static long[] getAllSongIdsWith(int type, long id) + { + if (type == TYPE_SONG) + return new long[] { id }; + + Cursor cursor; + if (type == MediaUtils.TYPE_PLAYLIST) + cursor = query(type, id, Song.EMPTY_PLAYLIST_PROJECTION, null); + else + cursor = query(type, id, Song.EMPTY_PROJECTION, null); if (cursor == null) return null; diff --git a/src/org/kreed/vanilla/Song.java b/src/org/kreed/vanilla/Song.java index 37f7c522..49b641c7 100644 --- a/src/org/kreed/vanilla/Song.java +++ b/src/org/kreed/vanilla/Song.java @@ -72,11 +72,11 @@ public class Song implements Parcelable { */ private static int mSongCount = -1; - private static final String[] EMPTY_PROJECTION = { + public static final String[] EMPTY_PROJECTION = { MediaStore.Audio.Media._ID, }; - private static final String[] FILLED_PROJECTION = { + public static final String[] FILLED_PROJECTION = { MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.TITLE, @@ -87,6 +87,21 @@ public class Song implements Parcelable { MediaStore.Audio.Media.DURATION }; + public static final String[] EMPTY_PLAYLIST_PROJECTION = { + MediaStore.Audio.Playlists.Members.AUDIO_ID, + }; + + public static final String[] FILLED_PLAYLIST_PROJECTION = { + MediaStore.Audio.Playlists.Members.AUDIO_ID, + MediaStore.Audio.Playlists.Members.DATA, + MediaStore.Audio.Playlists.Members.TITLE, + MediaStore.Audio.Playlists.Members.ALBUM, + MediaStore.Audio.Playlists.Members.ARTIST, + MediaStore.Audio.Playlists.Members.ALBUM_ID, + MediaStore.Audio.Playlists.Members.ARTIST_ID, + MediaStore.Audio.Playlists.Members.DURATION + }; + /** * Id of this song in the MediaStore */ @@ -287,7 +302,7 @@ public class Song implements Parcelable { * * @param cursor Cursor queried with FILLED_PROJECTION projection */ - private void populate(Cursor cursor) + public void populate(Cursor cursor) { id = cursor.getLong(0); path = cursor.getString(1); diff --git a/src/org/kreed/vanilla/SongSelector.java b/src/org/kreed/vanilla/SongSelector.java index 1cc7477f..0bc29468 100644 --- a/src/org/kreed/vanilla/SongSelector.java +++ b/src/org/kreed/vanilla/SongSelector.java @@ -469,7 +469,7 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem */ private void addToPlaylist(long playlistId, int type, long mediaId, CharSequence title) { - long[] ids = MediaUtils.getAllSongIdsWith(type, mediaId, null); + long[] ids = MediaUtils.getAllSongIdsWith(type, mediaId); Playlist.addToPlaylist(playlistId, ids); String message = getResources().getQuantityString(R.plurals.added_to_playlist, ids.length, ids.length, title); diff --git a/src/org/kreed/vanilla/SongTimeline.java b/src/org/kreed/vanilla/SongTimeline.java index f9014566..a19b980a 100644 --- a/src/org/kreed/vanilla/SongTimeline.java +++ b/src/org/kreed/vanilla/SongTimeline.java @@ -30,6 +30,7 @@ import java.util.ArrayList; import java.util.Collections; import android.content.Context; +import android.database.Cursor; import android.util.Log; /** @@ -378,12 +379,16 @@ public final class SongTimeline { */ public int chooseSongs(boolean enqueue, int type, long id, String selection) { - long[] songs = MediaUtils.getAllSongIdsWith(type, id, selection); - if (songs == null || songs.length == 0) + Cursor cursor; + if (type == MediaUtils.TYPE_PLAYLIST) + cursor = MediaUtils.query(type, id, Song.FILLED_PLAYLIST_PROJECTION, selection); + else + cursor = MediaUtils.query(type, id, Song.FILLED_PROJECTION, selection); + if (cursor == null) + return 0; + int count = cursor.getCount(); + if (count == 0) return 0; - - if (mShuffle) - MediaUtils.shuffle(songs); Song oldSong = getSong(+1); @@ -393,27 +398,31 @@ public final class SongTimeline { int i = mCurrentPos + mQueueOffset + 1; if (i < timeline.size()) timeline.subList(i, timeline.size()).clear(); - - for (int j = 0; j != songs.length; ++j) - timeline.add(new Song(songs[j])); - - mQueueOffset += songs.length; + mQueueOffset += count; } else { timeline.subList(mCurrentPos + 1, timeline.size()).clear(); - - for (int j = 0; j != songs.length; ++j) - timeline.add(new Song(songs[j])); - - mQueueOffset = songs.length; + mQueueOffset = count; } + + for (int j = 0; j != count; ++j) { + cursor.moveToNext(); + Song song = new Song(-1); + song.populate(cursor); + timeline.add(song); + } + + if (mShuffle) + Collections.shuffle(timeline.subList(timeline.size() - count, timeline.size()), ContextApplication.getRandom()); } + cursor.close(); mRepeatedSongs = null; + Song newSong = getSong(+1); if (newSong != oldSong && mCallback != null) mCallback.songReplaced(+1, newSong); - return songs.length; + return count; } /**