From the title of a music, a try toget the corresponding Artist, ALbum's name and Album's Cover. I use LoaderManager
and CursorLoader
. When the Activity is created I lunch the loader with getLoaderManager().initLoader(1, null, this)
. Here is the code of my loader:
On Create Loader
static final String[] PLAYER_SUMMARY_PROJECTION = { MediaStore.Audio.Media._ID, MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM};
static final String[] PLAYER_COVER_SUMMARY_PROJECTION = { MediaStore.Audio.Albums.ALBUM_ID, MediaStore.Audio.Albums.ALBUM_ART, MediaStore.Audio.Albums.ALBUM};
public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {
CursorLoader loader;
if(id==1){
String where = android.provider.MediaStore.Audio.Media.TITLE
+ "=?";
String whereVal[] = {dataalbumsTrackRequested};
loader = new CursorLoader(getActivity(), MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
PLAYER_SUMMARY_PROJECTION, where, whereVal,null); }
else{
String where2 = android.provider.MediaStore.Audio.Media.ALBUM
+ "=?";
String whereVal2[] = {album};
loader = new CursorLoader(getActivity(), MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
PLAYER_COVER_SUMMARY_PROJECTION, where2, whereVal2,null); }
return loader;
}
On Load Finish
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
if(loader.getId()==1){
//Fill the text view with their value
//Set Title
String title =cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
TextView titleView = (TextView)getView().findViewById(R.id.musicTitle);
titleView.setText(title);
//Set Artist
String artist =cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
TextView artistView = (TextView)getView().findViewById(R.id.artistName);
if (artist.equals("<unknown>")){artistView.setText(R.string.unknown_album);}
else { artistView.setText(artist);}
//Set Album
album =cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
TextView albumView = (TextView)getView().findViewById(R.id.albumTitle);
if (album.equals("<unknown>")){albumView.setText(R.string.unknown_album);}
else { albumView.setText(album);}
}
else {
ImageView coverView = (ImageView)getView().findViewById(R.id.playerCoverView);
if (cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART)).equals(null)){
//if no cover returned, display the by default (empty) cover
coverView.setImageResource(R.drawable.listcoverthumbnail);}
else{
Bitmap coverImage = BitmapFactory.decodeFile(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART)));
coverView.setImageBitmap(coverImage);}
getLoaderManager().initLoader(2, null, this);
}
The variable album
is defined for the whole class and dataalbumsTrackRequested
is a String equal to the title of the album desired.
The app crashes and I get :
06-19 16:21:42.720: E/AndroidRuntime(6516): Caused by: android.database.sqlite.SQLiteException: no such column: album_art: , while compiling: SELECT album_id, album_art, album FROM audio WHERE (album=?)
If I remove the second Loader (with Id=2), then of course the cover is not display, but the app doesn't crash. So the problem comes from the second Loader.
What am I doing wrong ? I'm sure the colomn album_art
exist as I've already achieved to get the cover like this in one of my other app. But here, I can't find where the bug comes from. Is it because I use multiple Loaders ?
Ok, problem solved.
1) In the second loader, I was using MediaStore.Audio.Media.ALBUM
instead of MediaStore.Audio.albums.ALBUM
2) My projection was PLAYER_COVER_SUMMARY_PROJECTION = { MediaStore.Audio.Albums.ALBUM_ID, MediaStore.Audio.Albums.ALBUM_ART, MediaStore.Audio.Albums.ALBUM}
instead of PLAYER_COVER_SUMMARY_PROJECTION = { MediaStore.Audio.Albums._ID, MediaStore.Audio.Albums.ALBUM_ART, MediaStore.Audio.Albums.ALBUM};
Then if you get the error 06-19 19:29:18.115: E/AndroidRuntime(22943): android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
, I solved it with cursor.move(cursor.getPosition()+2)
in OnLoadFinished
of the Loader
. It's an awful hack but it works.
Apparently I was not the only one with this problem (see this post for instance) but I've solved it in a another way.