Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutiple selection in playback queue #961

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 171 additions & 0 deletions app/src/main/java/ch/blinkenlights/android/vanilla/MediaUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,65 @@ private static QueryTask buildMediaQuery(int type, long id, String[] projection,
return result;
}

/**
* Builds a query that will return all the songs represented by the given
* parameters.
*
* @param type MediaUtils.TYPE_ARTIST, TYPE_ALBUM, or TYPE_SONG.
* @param idList The List of MediaStore ids of the song, artist, or album.
* @param projection The columns to query.
* @param select An extra selection to pass to the query, or null.
* @return The initialized query.
*/
private static QueryTask buildMultiMediaQuery(int type, long[] idList, String[] projection, String select)
{
StringBuilder selection = new StringBuilder();
String sort = DEFAULT_SORT;

if (select != null) {
selection.append(select);
selection.append(" AND ");
}

switch (type) {
case TYPE_SONG:
selection.append(MediaLibrary.SongColumns._ID + " IN (");
break;
case TYPE_ARTIST:
selection.append(MediaLibrary.ContributorColumns.ARTIST_ID + " IN (");
break;
case TYPE_ALBARTIST:
selection.append(MediaLibrary.ContributorColumns.ALBUMARTIST_ID + " IN (");
break;
case TYPE_COMPOSER:
selection.append(MediaLibrary.ContributorColumns.COMPOSER_ID + " IN (");
break;
case TYPE_ALBUM:
selection.append(MediaLibrary.SongColumns.ALBUM_ID + " IN (");
sort = ALBUM_SORT;
break;
case TYPE_GENRE:
// TODO _genre_id is not in VIEW_SONGS_ALBUMS_ARTISTS?
throw new UnsupportedOperationException("Not supported now");
// selection.append(MediaLibrary.GenreSongColumns._GENRE_ID + " IN (");
// break;
default:
throw new IllegalArgumentException("Invalid type specified: " + type);
}

String prefix = "";
for (long id: idList) {
selection.append(prefix);
prefix = ",";
selection.append(id);
}
selection.append(")");

QueryTask result = new QueryTask(MediaLibrary.VIEW_SONGS_ALBUMS_ARTISTS, projection, selection.toString(), null, sort);
result.type = type;
return result;
}

/**
* Builds a query that will return all the songs in the playlist with the
* given id.
Expand All @@ -208,6 +267,30 @@ public static QueryTask buildPlaylistQuery(long id, String[] projection) {
return result;
}

/**
* Builds a query that will return all the songs in the playlist with the
* given id.
*
* @param idList The id of the playlist in MediaStore.Audio.Playlists.
* @param projection The columns to query.
* @return The initialized query.
*/
public static QueryTask buildMultiPlaylistQuery(long[] idList, String[] projection) {
String sort = MediaLibrary.PlaylistSongColumns.POSITION;
StringBuilder selection = new StringBuilder();
selection.append(MediaLibrary.PlaylistSongColumns.PLAYLIST_ID + " IN (");
String prefix = "";
for (long id: idList) {
selection.append(prefix);
prefix = ",";
selection.append(id);
}
selection.append(")");
QueryTask result = new QueryTask(MediaLibrary.VIEW_PLAYLISTS_SONGS, projection, selection.toString(), null, sort);
result.type = TYPE_PLAYLIST;
return result;
}

/**
* Builds a query with the given information.
*
Expand Down Expand Up @@ -235,6 +318,35 @@ public static QueryTask buildQuery(int type, long id, String[] projection, Strin
}
}

/**
* Builds a query with the given information under multiple selection modes
* for playlist/queue.
*
* @param type Type the id represents. Must be one of the Song.TYPE_*
* constants.
* @param idList A list of ids of the element in the MediaStore content provider for
* the given type.
* @param projection The columns to query.
* @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 QueryTask buildMultiQuery(int type, long[] idList, String[] projection, String selection)
{
switch (type) {
case TYPE_ARTIST:
case TYPE_ALBARTIST:
case TYPE_COMPOSER:
case TYPE_ALBUM:
case TYPE_SONG:
case TYPE_GENRE:
return buildMultiMediaQuery(type, idList, projection, selection);
case TYPE_PLAYLIST:
return buildMultiPlaylistQuery(idList, projection);
default:
throw new IllegalArgumentException("Specified type not valid: " + type);
}
}

/**
* Query the MediaStore to determine the id of the genre the song belongs
* to.
Expand All @@ -256,6 +368,38 @@ public static long queryGenreForSong(Context context, long id) {
return 0;
}

/**
* Query the MediaStore to determine the id of the genre the song belongs
* to.
*
* @param context The context to use
* @param idList The list of ids of the song to query the genre for.
*/
public static long[] queryGenreForMultiSong(Context context, long[] idList) {
String[] projection = { MediaLibrary.GenreSongColumns._GENRE_ID };
StringBuilder query = new StringBuilder();
query.append(MediaLibrary.GenreSongColumns.SONG_ID + " IN (");
String prefix = "";
for (long id: idList) {
query.append(prefix);
prefix = ",";
query.append(id);
}
query.append(")");

Cursor cursor = MediaLibrary.queryLibrary(context, MediaLibrary.TABLE_GENRES_SONGS, projection, query.toString(), null, null);
long[] genreList = new long[cursor.getCount()];
if (cursor != null) {
int i = 0;
while (cursor.moveToNext()) {
genreList[i] = cursor.getLong(0);
i++;
}
cursor.close();
}
return genreList;
}

/**
* Shuffle a Song list using Collections.shuffle().
*
Expand Down Expand Up @@ -537,6 +681,33 @@ public static QueryTask buildFileQuery(String path, String[] projection, boolean
return result;
}

/**
* Build a query that will contain all the media under multiple given path.
*
* @param paths A list of paths
* @param projection The columns to query
* @param recursive whether or not to do a LIKE search, picking up child items.
* @return The initialized query.
*/
// TODO
// public static QueryTask buildMultiFileQuery(String[] paths, String[] projection, boolean recursive)
// {
// // Try to detect more popular mount point:
// path = sanitizeMediaPath(path);
// String query = MediaLibrary.SongColumns.PATH+" = ?";
//
// if (recursive) {
// // This is a LIKE query: add a slash to the directory if the current path
// // points to an existing one.
// path = addDirEndSlash(path) + "%";
// query = MediaLibrary.SongColumns.PATH+" LIKE ?";
// }
//
// QueryTask result = new QueryTask(MediaLibrary.VIEW_SONGS_ALBUMS_ARTISTS, projection, query, new String[]{ path }, FILE_SORT);
// result.type = TYPE_FILE;
// return result;
// }

/**
* Returns a (possibly empty) Cursor for given file path
* @param path The path to the file to be queried
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1880,7 +1880,6 @@ public void addSongs(QueryTask query)
mHandler.sendMessage(mHandler.obtainMessage(MSG_QUERY, query));
}


/**
* Enqueues all the songs with the same album/artist/genre as the passed
* song.
Expand Down Expand Up @@ -1918,6 +1917,57 @@ public void enqueueFromSong(Song song, int type)
addSongs(query);
}

/**
* Enqueues all songs selected, by passing the list of selected songs
*
* This will append the selected songs after the current queue
*
* @param songList A list of songs to base the query on
* @param type The media type, one of MediaUtils.TYPE_ALBUM, TYPE_ARTIST,
* or TYPE_GENRE
*/
public void enqueueFromMultiSong(Song[] songList, int type)
{
if (songList == null || songList.length == 0)
return;

long[] idList = new long[songList.length];
long[] songIdList = new long[songList.length];
for (int i = 0; i < songList.length; ++i) {
songIdList[i] = songList[i].id;
}
switch (type) {
case MediaUtils.TYPE_ARTIST:
for (int i = 0; i < songList.length; ++i) {
idList[i] = songList[i].artistId;
}
break;
case MediaUtils.TYPE_ALBUM:
for (int i = 0; i < songList.length; ++i) {
idList[i] = songList[i].albumId;
}
break;
case MediaUtils.TYPE_GENRE:
idList = MediaUtils.queryGenreForMultiSong(getApplicationContext(), songIdList);
break;
default:
throw new IllegalArgumentException("Unsupported media type: " + type);
}
StringBuilder selection = new StringBuilder();
selection.append("_id NOT IN (");
String prefix = "";
for (long id: songIdList) {
selection.append(prefix);
prefix = ",";
selection.append(id);
}
selection.append(")");

QueryTask query = MediaUtils.buildMultiQuery(type, idList, Song.FILLED_PROJECTION, selection.toString());
query.mode = SongTimeline.MODE_FLUSH_AND_PLAY_NEXT;
addSongs(query);
}

/**
* Clear the song queue.
*/
Expand Down Expand Up @@ -2457,4 +2507,12 @@ public void removeSongPosition(int which) {
mTimeline.removeSongPosition(which);
}

/**
* Removes a song from the queue
* @param pos index to remove
*/
public void removeSongPosition(ArrayList<Integer> pos) {
mTimeline.removeSongPosition(pos);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ private void sendUniqueMessage(int type, Object obj) {
*
* @param m3u the file to import
*/
private void importM3uPlaylist(File m3u) {;
private void importM3uPlaylist(File m3u) {
XT("importM3uPlaylist("+m3u+")");

if ((mSyncMode & SYNC_MODE_IMPORT) == 0)
Expand Down
Loading