From 8c6993537d2b41b908f41280c0dde8e10c3fad72 Mon Sep 17 00:00:00 2001 From: Xiao Bao Clark Date: Sun, 28 Feb 2016 12:08:58 +1100 Subject: [PATCH] Exclude empty genres from genre list Previously, genres without any songs associated with them would appear in the Library genre list. This commit adds a new query for genres that excludes these empty genres. This partially fixes issue #286 (empty genres cannot be deleted) - genres still can't be deleted, but the empty ones will no longer appear. --- .../android/vanilla/MediaAdapter.java | 5 +- .../android/vanilla/MediaUtils.java | 56 +++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/ch/blinkenlights/android/vanilla/MediaAdapter.java b/src/ch/blinkenlights/android/vanilla/MediaAdapter.java index 3d3236dc..69b1523f 100644 --- a/src/ch/blinkenlights/android/vanilla/MediaAdapter.java +++ b/src/ch/blinkenlights/android/vanilla/MediaAdapter.java @@ -344,7 +344,10 @@ public class MediaAdapter } QueryTask query; - if (limiter != null && limiter.type == MediaUtils.TYPE_GENRE) { + if(mType == MediaUtils.TYPE_GENRE && !returnSongs) { + query = MediaUtils.buildGenreExcludeEmptyQuery(projection, selection.toString(), + selectionArgs, sort); + } else if (limiter != null && limiter.type == MediaUtils.TYPE_GENRE) { // Genre is not standard metadata for MediaStore.Audio.Media. // We have to query it through a separate provider. : / query = MediaUtils.buildGenreQuery((Long)limiter.data, projection, selection.toString(), selectionArgs, sort, mType, returnSongs); diff --git a/src/ch/blinkenlights/android/vanilla/MediaUtils.java b/src/ch/blinkenlights/android/vanilla/MediaUtils.java index d6f1b547..098581bc 100644 --- a/src/ch/blinkenlights/android/vanilla/MediaUtils.java +++ b/src/ch/blinkenlights/android/vanilla/MediaUtils.java @@ -247,6 +247,62 @@ public class MediaUtils { return result; } + /** + * Creates a {@link QueryTask} for genres. The query will select only genres that have at least + * one song associated with them. + * + * @param projection The fields of the genre table that should be returned. + * @param selection Additional constraints for the query (added to the WHERE section). '?'s + * will be replaced by values in {@code selectionArgs}. Can be null. + * @param selectionArgs Arguments for {@code selection}. Can be null. See + * {@link android.content.ContentProvider#query(Uri, String[], String, String[], String)} + * @param sort How the returned genres should be sorted (added to the ORDER BY section) + * @return The QueryTask for the genres + */ + public static QueryTask buildGenreExcludeEmptyQuery(String[] projection, String selection, String[] selectionArgs, String sort) { + /* + * An example SQLite query that we're building in this function + SELECT DISTINCT _id, name + FROM audio_genres + WHERE + EXISTS( + SELECT audio_id, genre_id, audio._id + FROM audio_genres_map, audio + WHERE (genre_id == audio_genres._id) + AND (audio_id == audio._id)) + ORDER BY name DESC + */ + Uri uri = MediaStore.Audio.Genres.getContentUri("external"); + StringBuilder sql = new StringBuilder(); + // Don't want multiple identical genres + sql.append("DISTINCT "); + + // Add the projection fields to the query + sql.append(TextUtils.join(", ", projection)).append(' '); + + sql.append("FROM audio_genres "); + // Limit to genres that contain at least one valid song + sql.append("WHERE EXISTS( ") + .append("SELECT audio_id, genre_id, audio._id ") + .append("FROM audio_genres_map, audio ") + .append("WHERE (genre_id == audio_genres._id) AND (audio_id == audio._id) ") + .append(") "); + + if (!TextUtils.isEmpty(selection)) + sql.append(" AND(" + selection + ") "); + + if(!TextUtils.isEmpty(sort)) + sql.append(" ORDER BY ").append(sort); + + // Ignore the framework generated query + sql.append(" -- "); + String[] injectedProjection = new String[1]; + injectedProjection[0] = sql.toString(); + + // Don't pass the selection/sort as we've already added it to the query + return new QueryTask(uri, injectedProjection, null, selectionArgs, null); + } + /** * Builds a query with the given information. *