From ca3ce0897cbb70842024c5414c1130aac8f3388e Mon Sep 17 00:00:00 2001 From: Adrian Ulrich Date: Sun, 30 Oct 2016 13:30:45 +0100 Subject: [PATCH] improve sorting of results returned by buildSongQuery() --- .../android/vanilla/MediaAdapter.java | 51 +++++++++---------- .../android/vanilla/MediaUtils.java | 6 +-- 2 files changed, 27 insertions(+), 30 deletions(-) diff --git a/src/ch/blinkenlights/android/vanilla/MediaAdapter.java b/src/ch/blinkenlights/android/vanilla/MediaAdapter.java index e5736a5e..5c6af109 100644 --- a/src/ch/blinkenlights/android/vanilla/MediaAdapter.java +++ b/src/ch/blinkenlights/android/vanilla/MediaAdapter.java @@ -124,10 +124,6 @@ public class MediaAdapter * The constraint used for filtering, set by the search box. */ private String mConstraint; - /** - * The sort order for use with buildSongQuery(). - */ - private String mSongSort; /** * The human-readable descriptions for each sort mode. */ @@ -136,7 +132,12 @@ public class MediaAdapter * An array ORDER BY expressions for each sort mode. %1$s is replaced by * ASC or DESC as appropriate before being passed to the query. */ - private String[] mSortValues; + private String[] mAdapterSortValues; + /** + * Same as mAdapterSortValues, but describes the query to do if we + * are returning songs for a `foreign' adapter (which migt have different column names) + */ + private String[] mSongSortValues; /** * The index of the current of the current sort mode in mSortValues, or * the inverse of the index (in which case sort should be descending @@ -191,18 +192,18 @@ public class MediaAdapter mStore = MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI; mFields = new String[] { MediaStore.Audio.Artists.ARTIST }; mFieldKeys = new String[] { MediaStore.Audio.Artists.ARTIST_KEY }; - mSongSort = MediaUtils.DEFAULT_SORT; mSortEntries = new int[] { R.string.name, R.string.number_of_tracks }; - mSortValues = new String[] { "artist_key %1$s", "number_of_tracks %1$s,artist_key %1$s" }; + mAdapterSortValues = new String[] { "artist_key %1$s", "number_of_tracks %1$s,artist_key %1$s" }; + mSongSortValues = new String[] { "artist_key %1$s,track", "artist_key %1$s,track" /* cannot sort by number_of_tracks */ }; break; case MediaUtils.TYPE_ALBUM: mStore = MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI; mFields = new String[] { MediaStore.Audio.Albums.ALBUM, MediaStore.Audio.Albums.ARTIST }; // Why is there no artist_key column constant in the album MediaStore? The column does seem to exist. mFieldKeys = new String[] { MediaStore.Audio.Albums.ALBUM_KEY, "artist_key" }; - mSongSort = MediaUtils.ALBUM_SORT; mSortEntries = new int[] { R.string.name, R.string.artist_album, R.string.artist_year_album, R.string.number_of_tracks, R.string.date_added }; - mSortValues = new String[] { "album_key %1$s", "artist_key %1$s,album_key %1$s", "artist_key %1$s,minyear %1$s,album_key %1$s", "numsongs %1$s,album_key %1$s", "_id %1$s" }; + mAdapterSortValues = new String[] { "album_key %1$s", "artist_key %1$s,album_key %1$s", "artist_key %1$s,minyear %1$s,album_key %1$s", "numsongs %1$s,album_key %1$s", "_id %1$s" }; + mSongSortValues = new String[] { "album_key %1$s,track", "artist_key %1$s,album_key %1$s,track", "artist_key %1$s,year %1$s,album_key %1$s,track", "album_key %1$s,track", "album_id %1$s,track" }; break; case MediaUtils.TYPE_SONG: mStore = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; @@ -211,9 +212,10 @@ public class MediaAdapter mSortEntries = new int[] { R.string.name, R.string.artist_album_track, R.string.artist_album_title, R.string.artist_year_album, R.string.album_track, R.string.year, R.string.date_added, R.string.song_playcount }; - mSortValues = new String[] { "title_key %1$s", "artist_key %1$s,album_key %1$s,track", "artist_key %1$s,album_key %1$s,title_key %1$s", - "artist_key %1$s,year %1$s,album_key %1$s, track", "album_key %1$s,track", + mAdapterSortValues = new String[] { "title_key %1$s", "artist_key %1$s,album_key %1$s,track", "artist_key %1$s,album_key %1$s,title_key %1$s", + "artist_key %1$s,year %1$s,album_key %1$s,track", "album_key %1$s,track", "year %1$s,title_key %1$s","_id %1$s", SORT_MAGIC_PLAYCOUNT }; + mSongSortValues = mAdapterSortValues; // Songs covers are cached per-album mCoverCacheType = MediaUtils.TYPE_ALBUM; coverCacheKey = MediaStore.Audio.Albums.ALBUM_ID; @@ -223,7 +225,8 @@ public class MediaAdapter mFields = new String[] { MediaStore.Audio.Playlists.NAME }; mFieldKeys = null; mSortEntries = new int[] { R.string.name, R.string.date_added }; - mSortValues = new String[] { "name %1$s", "date_added %1$s" }; + mAdapterSortValues = new String[] { "name %1$s", "date_added %1$s" }; + mSongSortValues = null; mExpandable = true; break; case MediaUtils.TYPE_GENRE: @@ -231,7 +234,8 @@ public class MediaAdapter mFields = new String[] { MediaStore.Audio.Genres.NAME }; mFieldKeys = null; mSortEntries = new int[] { R.string.name }; - mSortValues = new String[] { "name %1$s" }; + mAdapterSortValues = new String[] { "name %1$s" }; + mSongSortValues = null; break; default: throw new IllegalArgumentException("Invalid value for type: " + type); @@ -255,7 +259,7 @@ public class MediaAdapter */ private String getFirstSortColumn() { int mode = mSortMode < 0 ? ~mSortMode : mSortMode; // get current sort mode - String column = SPACE_SPLIT.split(mSortValues[mode])[0]; + String column = SPACE_SPLIT.split(mAdapterSortValues[mode])[0]; if(column.endsWith("_key")) { // we want human-readable string, not machine-composed column = column.substring(0, column.length() - 4); } @@ -307,14 +311,12 @@ public class MediaAdapter sortDir = "ASC"; } - String sortStringRaw = mSortValues[mode]; + // Use the song-sort mapping if we are returning songs + String sortStringRaw = (returnSongs ? mSongSortValues[mode] : mAdapterSortValues[mode]); + String[] enrichedProjection = projection; - String[] enrichedProjection; // Magic sort mode: sort by playcount if (sortStringRaw == SORT_MAGIC_PLAYCOUNT) { - // special case, no explicit column to sort - enrichedProjection = projection; - ArrayList topSongs = (new PlayCountsHelper(mContext)).getTopSongs(4096); int sortWeight = -1 * topSongs.size(); // Sort mode is actually reversed (default: mostplayed -> leastplayed) @@ -325,16 +327,11 @@ public class MediaAdapter } sb.append(" ELSE 0 END %1s"); sortStringRaw = sb.toString(); - } else { - // enrich projection with sort column to build alphabet later + } else if (returnSongs == false) { + // This is an 'adapter native' query: include the first sorting column + // in the projection to make it useable for the fast-scroller enrichedProjection = Arrays.copyOf(projection, projection.length + 1); enrichedProjection[projection.length] = getFirstSortColumn(); - - if (returnSongs && mType != MediaUtils.TYPE_SONG) { - // We are in a non-song adapter but requested to return songs - sorting - // can only be done by using the adapters default sort mode :-( - sortStringRaw = mSongSort; - } } String sort = String.format(sortStringRaw, sortDir); diff --git a/src/ch/blinkenlights/android/vanilla/MediaUtils.java b/src/ch/blinkenlights/android/vanilla/MediaUtils.java index 326cdce1..a67e5634 100644 --- a/src/ch/blinkenlights/android/vanilla/MediaUtils.java +++ b/src/ch/blinkenlights/android/vanilla/MediaUtils.java @@ -91,17 +91,17 @@ public class MediaUtils { * The default sort order for media queries. First artist, then album, then * track number. */ - public static final String DEFAULT_SORT = "artist_key,album_key,track"; + private static final String DEFAULT_SORT = "artist_key,album_key,track"; /** * The default sort order for albums. First the album, then tracknumber */ - public static final String ALBUM_SORT = "album_key,track"; + private static final String ALBUM_SORT = "album_key,track"; /** * The default sort order for files. Simply use the path */ - public static final String FILE_SORT = "_data"; + private static final String FILE_SORT = "_data"; /** * Cached random instance.