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.
This commit is contained in:
Xiao Bao Clark 2016-02-28 12:08:58 +11:00
parent a347f38eb7
commit 8c6993537d
2 changed files with 60 additions and 1 deletions

View File

@ -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);

View File

@ -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.
*