Implemented showing artist names in song lists (#281)

* Song lists for artist, album, and overall now shows the artist name for each individual song
* Added display artist column to songs table. This required a DB upgrade and users should
  do a refresh for music items to be able to see the display artist in the song lists.
This commit is contained in:
Martijn Brekhof 2016-10-20 20:26:43 +02:00 committed by Synced Synapse
parent f0cd9a67f8
commit eedd1e99b4
9 changed files with 92 additions and 49 deletions

View File

@ -31,6 +31,7 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.xbmc.kore.host.HostInfo; import org.xbmc.kore.host.HostInfo;
import org.xbmc.kore.provider.MediaContract; import org.xbmc.kore.provider.MediaContract;
import org.xbmc.kore.provider.MediaProvider;
import org.xbmc.kore.testhelpers.Database; import org.xbmc.kore.testhelpers.Database;
import org.xbmc.kore.testhelpers.TestUtils; import org.xbmc.kore.testhelpers.TestUtils;
import org.xbmc.kore.testhelpers.Utils; import org.xbmc.kore.testhelpers.Utils;
@ -161,7 +162,7 @@ public class MediaProviderMusicTest {
public void queryAlbumSongsTest() { public void queryAlbumSongsTest() {
Uri uri = MediaContract.Songs.buildAlbumSongsListUri(hostInfo.getId(), TestValues.Album.albumId); Uri uri = MediaContract.Songs.buildAlbumSongsListUri(hostInfo.getId(), TestValues.Album.albumId);
Cursor cursor = contentResolver.query(uri, new String[] {MediaContract.Songs.SONGID}, null, null, null); Cursor cursor = contentResolver.query(uri, new String[] {MediaProvider.Qualified.SONGS_SONGID}, null, null, null);
assertNotNull(cursor); assertNotNull(cursor);
assertEquals("cursor size ", 17, cursor.getCount()); assertEquals("cursor size ", 17, cursor.getCount());

View File

@ -571,7 +571,7 @@ public class MediaContract {
String HOST_ID = "host_id"; String HOST_ID = "host_id";
String ALBUMID = "albumid"; String ALBUMID = "albumid";
String SONGID = "songid"; String SONGID = "songid";
String DISPLAYARTIST = "displayartist";
String DURATION = "duration"; String DURATION = "duration";
String THUMBNAIL = "thumbnail"; String THUMBNAIL = "thumbnail";
String FILE = "file"; String FILE = "file";

View File

@ -32,7 +32,9 @@ public class MediaDatabase extends SQLiteOpenHelper {
private static final String DB_NAME = "xbmc.sqlite"; private static final String DB_NAME = "xbmc.sqlite";
private static final int DB_VERSION_PRE_EVENT_SERVER = 4, private static final int DB_VERSION_PRE_EVENT_SERVER = 4,
DB_VERSION_PRE_SONG_ARTISTS = 5, DB_VERSION = 6; DB_VERSION_PRE_SONG_ARTISTS = 5,
DB_VERSION_PRE_SONG_DISPLAY_ARTIST = 6,
DB_VERSION = 7;
/** /**
* Tables exposed * Tables exposed
@ -94,7 +96,7 @@ public class MediaDatabase extends SQLiteOpenHelper {
* Join to get Songs for an Artist or Album with artist info and album info only if available * Join to get Songs for an Artist or Album with artist info and album info only if available
*/ */
String SONGS_FOR_ARTIST_AND_OR_ALBUM_JOIN = String SONGS_FOR_ARTIST_AND_OR_ALBUM_JOIN =
SONG_ARTISTS + " JOIN " + SONGS + " ON " + SONGS + " JOIN " + SONG_ARTISTS + " ON " +
SONG_ARTISTS + "." + MediaContract.SongArtists.HOST_ID + "=" + SONGS + "." + MediaContract.Songs.HOST_ID + SONG_ARTISTS + "." + MediaContract.SongArtists.HOST_ID + "=" + SONGS + "." + MediaContract.Songs.HOST_ID +
" AND " + " AND " +
SONG_ARTISTS + "." + MediaContract.SongArtists.SONGID + "=" + SONGS + "." + MediaContract.Songs.SONGID + SONG_ARTISTS + "." + MediaContract.SongArtists.SONGID + "=" + SONGS + "." + MediaContract.Songs.SONGID +
@ -102,10 +104,14 @@ public class MediaDatabase extends SQLiteOpenHelper {
SONG_ARTISTS + "." + MediaContract.SongArtists.HOST_ID + "=" + ARTISTS + "." + MediaContract.Artists.HOST_ID + SONG_ARTISTS + "." + MediaContract.SongArtists.HOST_ID + "=" + ARTISTS + "." + MediaContract.Artists.HOST_ID +
" AND " + " AND " +
SONG_ARTISTS + "." + MediaContract.SongArtists.ARTISTID + "=" + ARTISTS + "." + MediaContract.Artists.ARTISTID + SONG_ARTISTS + "." + MediaContract.SongArtists.ARTISTID + "=" + ARTISTS + "." + MediaContract.Artists.ARTISTID +
" LEFT JOIN " + ALBUM_ARTISTS + " ON " +
SONG_ARTISTS + "." + MediaContract.SongArtists.HOST_ID + "=" + ALBUM_ARTISTS + "." + MediaContract.AlbumArtists.HOST_ID +
" AND " +
SONGS + "." + MediaContract.Songs.ALBUMID + "=" + ALBUM_ARTISTS + "." + MediaContract.AlbumArtists.ALBUMID +
" LEFT JOIN " + ALBUMS + " ON " + " LEFT JOIN " + ALBUMS + " ON " +
SONG_ARTISTS + "." + MediaContract.SongArtists.HOST_ID + "=" + ALBUMS + "." + MediaContract.Albums.HOST_ID + SONG_ARTISTS + "." + MediaContract.SongArtists.HOST_ID + "=" + ALBUMS + "." + MediaContract.Albums.HOST_ID +
" AND " + " AND " +
SONGS + "." + MediaContract.Songs.ALBUMID + "=" + ALBUMS + "." + MediaContract.Albums.ALBUMID; ALBUM_ARTISTS + "." + MediaContract.AlbumArtists.ALBUMID + "=" + ALBUMS + "." + MediaContract.Albums.ALBUMID;
} }
@ -355,6 +361,7 @@ public class MediaDatabase extends SQLiteOpenHelper {
MediaContract.SongsColumns.FILE + " TEXT, " + MediaContract.SongsColumns.FILE + " TEXT, " +
MediaContract.SongsColumns.TRACK + " INTEGER, " + MediaContract.SongsColumns.TRACK + " INTEGER, " +
MediaContract.SongsColumns.TITLE + " TEXT, " + MediaContract.SongsColumns.TITLE + " TEXT, " +
MediaContract.SongsColumns.DISPLAYARTIST + " TEXT, " +
"UNIQUE (" + "UNIQUE (" +
MediaContract.SongsColumns.HOST_ID + ", " + MediaContract.SongsColumns.HOST_ID + ", " +
MediaContract.SongsColumns.ALBUMID + ", " + MediaContract.SongsColumns.ALBUMID + ", " +
@ -452,6 +459,7 @@ public class MediaDatabase extends SQLiteOpenHelper {
db.execSQL(buildHostsDeleteTrigger(Tables.SONGS, MediaContract.SongsColumns.HOST_ID)); db.execSQL(buildHostsDeleteTrigger(Tables.SONGS, MediaContract.SongsColumns.HOST_ID));
db.execSQL(buildHostsDeleteTrigger(Tables.AUDIO_GENRES, MediaContract.AudioGenresColumns.HOST_ID)); db.execSQL(buildHostsDeleteTrigger(Tables.AUDIO_GENRES, MediaContract.AudioGenresColumns.HOST_ID));
db.execSQL(buildHostsDeleteTrigger(Tables.ALBUM_ARTISTS, MediaContract.AlbumArtistsColumns.HOST_ID)); db.execSQL(buildHostsDeleteTrigger(Tables.ALBUM_ARTISTS, MediaContract.AlbumArtistsColumns.HOST_ID));
db.execSQL(buildHostsDeleteTrigger(Tables.SONG_ARTISTS, MediaContract.SongArtistsColumns.HOST_ID));
db.execSQL(buildHostsDeleteTrigger(Tables.ALBUM_GENRES, MediaContract.AlbumGenresColumns.HOST_ID)); db.execSQL(buildHostsDeleteTrigger(Tables.ALBUM_GENRES, MediaContract.AlbumGenresColumns.HOST_ID));
db.execSQL(buildHostsDeleteTrigger(Tables.MUSIC_VIDEOS, MediaContract.MusicVideosColumns.HOST_ID)); db.execSQL(buildHostsDeleteTrigger(Tables.MUSIC_VIDEOS, MediaContract.MusicVideosColumns.HOST_ID));
@ -478,6 +486,10 @@ public class MediaDatabase extends SQLiteOpenHelper {
" INTEGER DEFAULT " + HostInfo.DEFAULT_EVENT_SERVER_PORT + ";"); " INTEGER DEFAULT " + HostInfo.DEFAULT_EVENT_SERVER_PORT + ";");
case DB_VERSION_PRE_SONG_ARTISTS: case DB_VERSION_PRE_SONG_ARTISTS:
createSongArtistsTable(db); createSongArtistsTable(db);
case DB_VERSION_PRE_SONG_DISPLAY_ARTIST:
db.execSQL("ALTER TABLE " + Tables.SONGS +
" ADD COLUMN " + MediaContract.SongsColumns.DISPLAYARTIST +
" TEXT;");
} }
} }

View File

@ -23,7 +23,6 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.net.Uri; import android.net.Uri;
import android.provider.BaseColumns; import android.provider.BaseColumns;
import android.support.annotation.Nullable;
import org.xbmc.kore.utils.LogUtils; import org.xbmc.kore.utils.LogUtils;
import org.xbmc.kore.utils.SelectionBuilder; import org.xbmc.kore.utils.SelectionBuilder;
@ -671,8 +670,9 @@ public class MediaProvider extends ContentProvider {
.mapToTable(MediaContract.Songs.SONGID, MediaDatabase.Tables.SONGS) .mapToTable(MediaContract.Songs.SONGID, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.Songs.TITLE, MediaDatabase.Tables.SONGS) .mapToTable(MediaContract.Songs.TITLE, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.Songs.ALBUMID, MediaDatabase.Tables.SONGS) .mapToTable(MediaContract.Songs.ALBUMID, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.Songs.UPDATED, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.Songs.THUMBNAIL, MediaDatabase.Tables.SONGS) .mapToTable(MediaContract.Songs.THUMBNAIL, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.Songs.DISPLAYARTIST, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.AlbumArtists.ARTISTID, MediaDatabase.Tables.ALBUM_ARTISTS)
.mapToTable(MediaContract.SongArtists.ARTISTID, MediaDatabase.Tables.SONG_ARTISTS) .mapToTable(MediaContract.SongArtists.ARTISTID, MediaDatabase.Tables.SONG_ARTISTS)
.where(Qualified.SONGS_HOST_ID + "=?", hostId) .where(Qualified.SONGS_HOST_ID + "=?", hostId)
.groupBy(Qualified.SONGS_SONGID); .groupBy(Qualified.SONGS_SONGID);
@ -681,8 +681,8 @@ public class MediaProvider extends ContentProvider {
final String hostId = MediaContract.Hosts.getHostId(uri); final String hostId = MediaContract.Hosts.getHostId(uri);
final String albumId = MediaContract.Albums.getAlbumId(uri); final String albumId = MediaContract.Albums.getAlbumId(uri);
return builder.table(MediaDatabase.Tables.SONGS) return builder.table(MediaDatabase.Tables.SONGS)
.where(MediaContract.Songs.HOST_ID + "=?", hostId) .where(Qualified.SONGS_HOST_ID + "=?", hostId)
.where(MediaContract.Songs.ALBUMID + "=?", albumId); .where(Qualified.SONGS_ALBUMID + "=?", albumId);
} }
case SONGS_ID: { case SONGS_ID: {
final String hostId = MediaContract.Hosts.getHostId(uri); final String hostId = MediaContract.Hosts.getHostId(uri);
@ -737,11 +737,14 @@ public class MediaProvider extends ContentProvider {
.mapToTable(MediaContract.Songs.SONGID, MediaDatabase.Tables.SONGS) .mapToTable(MediaContract.Songs.SONGID, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.Songs.TITLE, MediaDatabase.Tables.SONGS) .mapToTable(MediaContract.Songs.TITLE, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.Songs.ALBUMID, MediaDatabase.Tables.SONGS) .mapToTable(MediaContract.Songs.ALBUMID, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.Songs.UPDATED, MediaDatabase.Tables.SONGS) .mapToTable(MediaContract.Songs.DISPLAYARTIST, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.Songs.THUMBNAIL, MediaDatabase.Tables.SONGS) .mapToTable(MediaContract.AlbumArtists.ARTISTID, MediaDatabase.Tables.ALBUM_ARTISTS)
.mapToTable(MediaContract.SongArtists.ARTISTID, MediaDatabase.Tables.SONG_ARTISTS) .mapToTable(MediaContract.SongArtists.ARTISTID, MediaDatabase.Tables.SONG_ARTISTS)
.where(Qualified.SONG_ARTISTS_HOST_ID + "=?", hostId) .where(Qualified.SONG_ARTISTS_HOST_ID + "=?", hostId)
.where(Qualified.SONG_ARTISTS_ARTISTID + "=?", artistId); .where(Qualified.SONG_ARTISTS_ARTISTID + "=?"
+ " OR " +
Qualified.ALBUM_ARTISTS_ARTISTID + "=?", artistId, artistId)
.groupBy(Qualified.SONGS_ID);
} }
case ALBUM_ARTISTS_LIST: { case ALBUM_ARTISTS_LIST: {
// Artists for Album // Artists for Album
@ -806,6 +809,14 @@ public class MediaProvider extends ContentProvider {
* parent {@link MediaDatabase.Tables}. Used when needed to work around SQL ambiguity. * parent {@link MediaDatabase.Tables}. Used when needed to work around SQL ambiguity.
*/ */
public interface Qualified { public interface Qualified {
String ALBUMS_TITLE =
MediaDatabase.Tables.ALBUMS + "." + MediaContract.Albums.TITLE;
String ALBUMS_GENRE =
MediaDatabase.Tables.ALBUMS + "." + MediaContract.Albums.GENRE;
String ALBUMS_YEAR =
MediaDatabase.Tables.ALBUMS + "." + MediaContract.Albums.YEAR;
String ALBUMS_THUMBNAIL =
MediaDatabase.Tables.ALBUMS + "." + MediaContract.Albums.THUMBNAIL;
String ALBUM_ARTISTS_HOST_ID = String ALBUM_ARTISTS_HOST_ID =
MediaDatabase.Tables.ALBUM_ARTISTS + "." + MediaContract.AlbumArtists.HOST_ID; MediaDatabase.Tables.ALBUM_ARTISTS + "." + MediaContract.AlbumArtists.HOST_ID;
String ALBUM_ARTISTS_ARTISTID = String ALBUM_ARTISTS_ARTISTID =
@ -818,10 +829,24 @@ public class MediaProvider extends ContentProvider {
MediaDatabase.Tables.ALBUM_GENRES + "." + MediaContract.AlbumGenres.GENREID; MediaDatabase.Tables.ALBUM_GENRES + "." + MediaContract.AlbumGenres.GENREID;
String ALBUM_GENRES_ALBUMID = String ALBUM_GENRES_ALBUMID =
MediaDatabase.Tables.ALBUM_GENRES + "." + MediaContract.AlbumGenres.ALBUMID; MediaDatabase.Tables.ALBUM_GENRES + "." + MediaContract.AlbumGenres.ALBUMID;
String SONGS_ID =
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs._ID;
String SONGS_TRACK =
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.TRACK;
String SONGS_DURATION =
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.DURATION;
String SONGS_FILE =
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.FILE;
String SONGS_HOST_ID = String SONGS_HOST_ID =
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.HOST_ID; MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.HOST_ID;
String SONGS_SONGID = String SONGS_SONGID =
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.SONGID; MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.SONGID;
String SONGS_DISPLAYARTIST =
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.DISPLAYARTIST;
String SONGS_TITLE =
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.TITLE;
String SONGS_ALBUMID =
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.ALBUMID;
String SONG_ARTISTS_HOST_ID = String SONG_ARTISTS_HOST_ID =
MediaDatabase.Tables.SONG_ARTISTS + "." + MediaContract.SongArtists.HOST_ID; MediaDatabase.Tables.SONG_ARTISTS + "." + MediaContract.SongArtists.HOST_ID;
String SONG_ARTISTS_ARTISTID = String SONG_ARTISTS_ARTISTID =

View File

@ -272,7 +272,8 @@ public class SyncMusic extends SyncItem {
//AudioType.FieldsSong.LASTPLAYED, AudioType.FieldsSong.DISC, //AudioType.FieldsSong.LASTPLAYED, AudioType.FieldsSong.DISC,
//AudioType.FieldsSong.GENREID, //AudioType.FieldsSong.GENREID,
AudioType.FieldsSong.ARTISTID, AudioType.FieldsSong.ARTISTID,
//AudioType.FieldsSong.DISPLAYARTIST, AudioType.FieldsSong.ALBUMARTISTID // AudioType.FieldsSong.ALBUMARTISTID,
AudioType.FieldsSong.DISPLAYARTIST
}; };
/** /**

View File

@ -336,6 +336,7 @@ public class SyncUtils {
songValues.put(MediaContract.Songs.FILE, song.file); songValues.put(MediaContract.Songs.FILE, song.file);
songValues.put(MediaContract.Songs.TRACK, song.track); songValues.put(MediaContract.Songs.TRACK, song.track);
songValues.put(MediaContract.Songs.TITLE, song.title); songValues.put(MediaContract.Songs.TITLE, song.title);
songValues.put(MediaContract.Songs.DISPLAYARTIST, song.displayartist);
return songValues; return songValues;
} }

View File

@ -60,6 +60,7 @@ import org.xbmc.kore.jsonrpc.method.Player;
import org.xbmc.kore.jsonrpc.method.Playlist; import org.xbmc.kore.jsonrpc.method.Playlist;
import org.xbmc.kore.jsonrpc.type.PlaylistType; import org.xbmc.kore.jsonrpc.type.PlaylistType;
import org.xbmc.kore.provider.MediaContract; import org.xbmc.kore.provider.MediaContract;
import org.xbmc.kore.provider.MediaDatabase;
import org.xbmc.kore.utils.FileDownloadHelper; import org.xbmc.kore.utils.FileDownloadHelper;
import org.xbmc.kore.utils.LogUtils; import org.xbmc.kore.utils.LogUtils;
import org.xbmc.kore.utils.UIUtils; import org.xbmc.kore.utils.UIUtils;
@ -651,7 +652,7 @@ public class AlbumDetailsFragment extends AbstractDetailsFragment
.inflate(R.layout.list_item_song, songListView, false); .inflate(R.layout.list_item_song, songListView, false);
TextView songTitle = (TextView)songView.findViewById(R.id.song_title); TextView songTitle = (TextView)songView.findViewById(R.id.song_title);
TextView trackNumber = (TextView)songView.findViewById(R.id.track_number); TextView trackNumber = (TextView)songView.findViewById(R.id.track_number);
TextView duration = (TextView)songView.findViewById(R.id.duration); TextView details = (TextView)songView.findViewById(R.id.details);
ImageView contextMenu = (ImageView)songView.findViewById(R.id.list_context_menu); ImageView contextMenu = (ImageView)songView.findViewById(R.id.list_context_menu);
// Add this song to the list // Add this song to the list
@ -665,8 +666,14 @@ public class AlbumDetailsFragment extends AbstractDetailsFragment
songInfoList.add(songInfo); songInfoList.add(songInfo);
songTitle.setText(songInfo.title); songTitle.setText(songInfo.title);
trackNumber.setText(String.valueOf(songInfo.track)); trackNumber.setText(String.valueOf(songInfo.track));
duration.setText(UIUtils.formatTime(cursor.getInt(AlbumSongsListQuery.DURATION)));
String artist = cursor.getString(AlbumSongsListQuery.ARTIST);
String duration = UIUtils.formatTime(cursor.getInt(AlbumSongsListQuery.DURATION));
String detailsText = TextUtils.isEmpty(artist) ? duration : duration + " | " + artist;
details.setText(detailsText);
contextMenu.setTag(songInfo); contextMenu.setTag(songInfo);
contextMenu.setOnClickListener(songItemMenuClickListener); contextMenu.setOnClickListener(songItemMenuClickListener);
@ -737,7 +744,7 @@ public class AlbumDetailsFragment extends AbstractDetailsFragment
} }
/** /**
* Movie cast list query parameters. * Album songs list query parameters.
*/ */
public interface AlbumSongsListQuery { public interface AlbumSongsListQuery {
String[] PROJECTION = { String[] PROJECTION = {
@ -747,15 +754,17 @@ public class AlbumDetailsFragment extends AbstractDetailsFragment
MediaContract.Songs.DURATION, MediaContract.Songs.DURATION,
MediaContract.Songs.FILE, MediaContract.Songs.FILE,
MediaContract.Songs.SONGID, MediaContract.Songs.SONGID,
MediaContract.Songs.DISPLAYARTIST
}; };
String SORT = MediaContract.Songs.TRACK + " ASC"; String SORT = MediaContract.Songs.TRACK + " ASC";
final int ID = 0; int ID = 0;
final int TITLE = 1; int TITLE = 1;
final int TRACK = 2; int TRACK = 2;
final int DURATION = 3; int DURATION = 3;
final int FILE = 4; int FILE = 4;
final int SONGID = 5; int SONGID = 5;
int ARTIST = 6;
} }
} }

View File

@ -44,6 +44,7 @@ import org.xbmc.kore.host.HostManager;
import org.xbmc.kore.jsonrpc.type.PlaylistType; import org.xbmc.kore.jsonrpc.type.PlaylistType;
import org.xbmc.kore.provider.MediaContract; import org.xbmc.kore.provider.MediaContract;
import org.xbmc.kore.provider.MediaDatabase; import org.xbmc.kore.provider.MediaDatabase;
import org.xbmc.kore.provider.MediaProvider;
import org.xbmc.kore.service.library.LibrarySyncService; import org.xbmc.kore.service.library.LibrarySyncService;
import org.xbmc.kore.utils.LogUtils; import org.xbmc.kore.utils.LogUtils;
import org.xbmc.kore.utils.MediaPlayerUtils; import org.xbmc.kore.utils.MediaPlayerUtils;
@ -136,23 +137,20 @@ public class SongsListFragment extends AbstractCursorListFragment {
*/ */
public interface SongsListQuery { public interface SongsListQuery {
String[] PROJECTION = { String[] PROJECTION = {
MediaDatabase.Tables.SONGS + "." + BaseColumns._ID, MediaProvider.Qualified.SONGS_ID,
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.TITLE, MediaProvider.Qualified.SONGS_TITLE,
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.TRACK, MediaProvider.Qualified.SONGS_TRACK,
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.DURATION, MediaProvider.Qualified.SONGS_DURATION,
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.FILE, MediaProvider.Qualified.SONGS_FILE,
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.SONGID, MediaProvider.Qualified.SONGS_SONGID,
MediaDatabase.Tables.ALBUMS + "." + MediaContract.Albums.TITLE, MediaProvider.Qualified.SONGS_DISPLAYARTIST,
MediaDatabase.Tables.ALBUMS + "." + MediaContract.Albums.DISPLAYARTIST, MediaProvider.Qualified.ALBUMS_TITLE,
MediaDatabase.Tables.ALBUMS + "." + MediaContract.Albums.GENRE, MediaProvider.Qualified.ALBUMS_GENRE,
MediaDatabase.Tables.ALBUMS + "." + MediaContract.Albums.YEAR, MediaProvider.Qualified.ALBUMS_YEAR,
MediaDatabase.Tables.ALBUMS + "." + MediaContract.Albums.THUMBNAIL, MediaProvider.Qualified.ALBUMS_THUMBNAIL
MediaDatabase.Tables.ARTISTS + "." + MediaContract.Artists.ARTIST
}; };
String SORT = MediaDatabase.sortCommonTokens(MediaDatabase.Tables.SONGS String SORT = MediaDatabase.sortCommonTokens(MediaProvider.Qualified.SONGS_TITLE) + " ASC";
+ "." +
MediaContract.Songs.TITLE) + " ASC";
int ID = 0; int ID = 0;
int TITLE = 1; int TITLE = 1;
@ -160,12 +158,11 @@ public class SongsListFragment extends AbstractCursorListFragment {
int DURATION = 3; int DURATION = 3;
int FILE = 4; int FILE = 4;
int SONGID = 5; int SONGID = 5;
int ALBUMTITLE = 6; int SONGARTIST = 6;
int ALBUMARTIST = 7; int ALBUMTITLE = 7;
int GENRE = 8; int GENRE = 8;
int YEAR = 9; int YEAR = 9;
int THUMBNAIL = 10; int THUMBNAIL = 10;
int ARTIST = 11;
} }
private class SongsAdapter extends CursorAdapter { private class SongsAdapter extends CursorAdapter {
@ -213,10 +210,7 @@ public class SongsListFragment extends AbstractCursorListFragment {
viewHolder.title.setText(title); viewHolder.title.setText(title);
String artist = cursor.getString(SongsListQuery.ALBUMARTIST); String artist = cursor.getString(SongsListQuery.SONGARTIST);
if (TextUtils.isEmpty(artist))
artist = cursor.getString(SongsListQuery.ARTIST);
viewHolder.artist.setText(artist); viewHolder.artist.setText(artist);
int year = cursor.getInt(SongsListQuery.YEAR); int year = cursor.getInt(SongsListQuery.YEAR);

View File

@ -16,10 +16,10 @@
--> -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container" android:id="@+id/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"> android:background="?attr/selectableItemBackground">
<TextView <TextView
android:id="@+id/track_number" android:id="@+id/track_number"
@ -53,7 +53,7 @@
android:layout_toStartOf="@id/list_context_menu" android:layout_toStartOf="@id/list_context_menu"
android:layout_alignBottom="@id/track_number"/> android:layout_alignBottom="@id/track_number"/>
<TextView <TextView
android:id="@+id/duration" android:id="@+id/details"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignLeft="@id/song_title" android:layout_alignLeft="@id/song_title"