Genres tab
This commit is contained in:
parent
b8e608816a
commit
944b5fc1fa
16 changed files with 739 additions and 28 deletions
|
|
@ -0,0 +1,129 @@
|
|||
package com.kabouzeid.gramophone.loader;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.provider.MediaStore.Audio.Genres;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.model.Genre;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class GenreLoader {
|
||||
|
||||
@NonNull
|
||||
public static ArrayList<Genre> getAllGenres(@NonNull final Context context) {
|
||||
final String[] projection = new String[]{
|
||||
Genres._ID,
|
||||
Genres.NAME
|
||||
};
|
||||
final String selection = Genres._ID + " IN" +
|
||||
" (SELECT " + Genres.Members.GENRE_ID + " FROM audio_genres_map WHERE " + Genres.Members.AUDIO_ID + " IN" +
|
||||
" (SELECT " + Genres._ID + " FROM audio_meta WHERE " + SongLoader.BASE_SELECTION + "))";
|
||||
|
||||
final Cursor cursor = context.getContentResolver().query(
|
||||
Genres.EXTERNAL_CONTENT_URI,
|
||||
projection, selection, null, PreferenceUtil.getInstance(context).getGenreSortOrder());
|
||||
|
||||
return getGenresFromCursor(context, cursor);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static ArrayList<Song> getSongs(@NonNull final Context context, final int genreId) {
|
||||
// The genres table only stores songs that have a genre specified,
|
||||
// so we need to get songs without a genre a different way.
|
||||
if (genreId == -1) {
|
||||
return getSongsWithNoGenre(context);
|
||||
}
|
||||
|
||||
final Cursor cursor = context.getContentResolver().query(
|
||||
Genres.Members.getContentUri("external", genreId),
|
||||
SongLoader.BASE_PROJECTION, SongLoader.BASE_SELECTION, null, null);
|
||||
|
||||
return SongLoader.getSongs(cursor);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static ArrayList<Genre> getGenresFromCursor(@NonNull final Context context, @Nullable final Cursor cursor) {
|
||||
final ArrayList<Genre> genres = new ArrayList<>();
|
||||
|
||||
if (hasSongsWithNoGenre(context)) {
|
||||
genres.add(new Genre(context.getResources().getString(R.string.unknown_genre)));
|
||||
}
|
||||
|
||||
if (cursor != null) {
|
||||
if (cursor.moveToFirst()) {
|
||||
do {
|
||||
genres.add(getGenreFromCursor(cursor));
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
return genres;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static Genre getGenreFromCursor(@NonNull final Cursor cursor) {
|
||||
final int id = cursor.getInt(0);
|
||||
final String name = cursor.getString(1);
|
||||
return new Genre(id, name);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static ArrayList<Song> getSongsWithNoGenre(@NonNull final Context context) {
|
||||
final Cursor cursor = makeAllSongsWithGenreCursor(context);
|
||||
ArrayList<Song> songs = new ArrayList<>();
|
||||
final int[] songIds = getSongIdsFromCursor(cursor);
|
||||
if (songIds.length > 0) {
|
||||
songs = SongLoader.getSongsNotIn(context, songIds);
|
||||
}
|
||||
return songs;
|
||||
}
|
||||
|
||||
private static int[] getSongIdsFromCursor(@Nullable final Cursor cursor) {
|
||||
if (cursor == null) {
|
||||
return new int[]{};
|
||||
}
|
||||
|
||||
int[] songIds = new int[cursor.getCount()];
|
||||
if (cursor.moveToFirst()) {
|
||||
int i = 0;
|
||||
do {
|
||||
songIds[i] = cursor.getInt(0);
|
||||
i++;
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
cursor.close();
|
||||
return songIds;
|
||||
}
|
||||
|
||||
private static boolean hasSongsWithNoGenre(@NonNull final Context context) {
|
||||
final Cursor allSongsCursor = SongLoader.makeSongCursor(context, null, null);
|
||||
final Cursor allSongsWithGenreCursor = makeAllSongsWithGenreCursor(context);
|
||||
|
||||
if (allSongsCursor == null || allSongsWithGenreCursor == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final boolean hasSongsWithNoGenre = allSongsCursor.getCount() > allSongsWithGenreCursor.getCount();
|
||||
allSongsCursor.close();
|
||||
allSongsWithGenreCursor.close();
|
||||
return hasSongsWithNoGenre;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Cursor makeAllSongsWithGenreCursor(@NonNull final Context context) {
|
||||
try {
|
||||
return context.getContentResolver().query(
|
||||
Uri.parse("content://media/external/audio/genres/all/members"),
|
||||
new String[]{Genres.Members.AUDIO_ID}, null, null, null);
|
||||
} catch (SecurityException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,12 +12,26 @@ import com.kabouzeid.gramophone.model.Song;
|
|||
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
public class SongLoader {
|
||||
protected static final String BASE_SELECTION = AudioColumns.IS_MUSIC + "=1" + " AND " + AudioColumns.TITLE + " != ''";
|
||||
protected static final String[] BASE_PROJECTION = new String[]{
|
||||
BaseColumns._ID, // 0
|
||||
AudioColumns.TITLE, // 1
|
||||
AudioColumns.TRACK, // 2
|
||||
AudioColumns.YEAR, // 3
|
||||
AudioColumns.DURATION, // 4
|
||||
AudioColumns.DATA, // 5
|
||||
AudioColumns.DATE_MODIFIED, // 6
|
||||
AudioColumns.ALBUM_ID, // 7
|
||||
AudioColumns.ALBUM, // 8
|
||||
AudioColumns.ARTIST_ID, // 9
|
||||
AudioColumns.ARTIST, // 10
|
||||
};
|
||||
|
||||
@NonNull
|
||||
public static ArrayList<Song> getAllSongs(@NonNull Context context) {
|
||||
|
|
@ -31,6 +45,13 @@ public class SongLoader {
|
|||
return getSongs(cursor);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static ArrayList<Song> getSongsNotIn(@NonNull final Context context, final int[] query) {
|
||||
final String ids = convertArrayToQueryList(query);
|
||||
Cursor cursor = makeSongCursor(context, AudioColumns._ID + " NOT IN " + ids, null);
|
||||
return getSongs(cursor);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static Song getSong(@NonNull final Context context, final int queryId) {
|
||||
Cursor cursor = makeSongCursor(context, AudioColumns._ID + "=?", new String[]{String.valueOf(queryId)});
|
||||
|
|
@ -96,22 +117,13 @@ public class SongLoader {
|
|||
|
||||
try {
|
||||
return context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
||||
new String[]{
|
||||
BaseColumns._ID,// 0
|
||||
AudioColumns.TITLE,// 1
|
||||
AudioColumns.TRACK,// 2
|
||||
AudioColumns.YEAR,// 3
|
||||
AudioColumns.DURATION,// 4
|
||||
AudioColumns.DATA,// 5
|
||||
AudioColumns.DATE_MODIFIED,// 6
|
||||
AudioColumns.ALBUM_ID,// 7
|
||||
AudioColumns.ALBUM,// 8
|
||||
AudioColumns.ARTIST_ID,// 9
|
||||
AudioColumns.ARTIST,// 10
|
||||
|
||||
}, baseSelection, selectionValues, sortOrder);
|
||||
BASE_PROJECTION, baseSelection, selectionValues, sortOrder);
|
||||
} catch (SecurityException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static String convertArrayToQueryList(final int[] array) {
|
||||
return "(" + Arrays.toString(array).replaceAll("\\[|\\]|\\s", "") + ")";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue