Search code examples
xamarinxamarin.androidmediastorealbumart

Populating a list of songs with Album Art - Not able to get Album art


I'm currently building a music browser/player of the music on a the device. I sucessufully populated the a listview with the names of the songs and their artist but I'm not able to show the albumart associated with the song. I'm not quite sure what is the correct path to get the album art & also how to correlate it with the songs. The code builds but not album art is showed up. I guess that albumArtUri is not good. Could you please help me to get the right albumart Uri?

Thank you for your help, it's appreciated :)

Julien

Here is my SongAdapter Code:

using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;

using Android.Provider;
using Android.Database;
using Android.Net;

namespace project
{
    public class SongsAdapter:CursorAdapter 
    {
        List<Song> songsList;
        Activity context;
        public SongsAdapter (Activity context, ICursor cursor, List<Song> theSongs): base(context,cursor)
        {
            this.context = context;
            songsList = theSongs;
        }

    public override void BindView(View view, Context context, ICursor cursor)
    {
        var song_title = view.FindViewById<TextView> (Resource.Id.song_title);
        var song_artist = view.FindViewById<TextView> (Resource.Id.song_artist);
        var song_album_art = view.FindViewById<ImageView> (Resource.Id.song_album_art);
        song_title.Text = songsList [cursor.Position].Title;
        song_artist.Text = songsList [cursor.Position].Artist;


        //If there is an image to display, it will display it. If not, it will use a default image
        if (songsList [cursor.Position].AlbumId == null) {
            song_album_art = view.FindViewById<ImageView> (Resource.Id.song_album_art);
            song_album_art.SetImageResource (Resource.Drawable.ic_action_user); //Image needs to be set
        } else {
            var songUri = ContentUris.WithAppendedId (MediaStore.Audio.Media.ExternalContentUri, songsList [cursor.Position].Id);
            var albumArtUri = Android.Net.Uri.WithAppendedPath(songUri,MediaStore.Audio.Albums.EntryContentType);

            song_album_art.SetImageURI (albumArtUri);
        }
    }

    public override View NewView(Context context, ICursor cursor, ViewGroup parent)
    {
        return this.context.LayoutInflater.Inflate(Resource.Layout.songslistitem, parent, false);
    }
}
}

Here is how I call the SongAdapter:

                ListView listView;
                view = LayoutInflater.From (container.Context).Inflate (Resource.Layout.songlist, container, false);
                listView = view.FindViewById<ListView> (Resource.Id.List);

                List<Song> songsList;

                var uri = MediaStore.Audio.Media.ExternalContentUri;
                string[] projection = {
                    MediaStore.Audio.Media.InterfaceConsts.Id,
                    MediaStore.Audio.Media.InterfaceConsts.AlbumId,
                    MediaStore.Audio.Media.InterfaceConsts.Title,
                    MediaStore.Audio.Media.InterfaceConsts.Artist,
                };
                var loader = new CursorLoader (container.Context, uri, projection, null, null, null);
                var cursor = (ICursor)loader.LoadInBackground ();
                songsList = new List<Song> ();
                if (cursor.MoveToFirst ()) {
                    do {
                        songsList.Add (new Song {
                            Id = cursor.GetLong (cursor.GetColumnIndex (projection [0])),
                            AlbumId = cursor.GetString (cursor.GetColumnIndex (projection [1])),
                            Title = cursor.GetString (cursor.GetColumnIndex (projection [2])),
                            Artist = cursor.GetString (cursor.GetColumnIndex (projection [3]))
                        });
                    } while (cursor.MoveToNext ());
                }

                listView.Adapter = new SongsAdapter (context,cursor,songsList);

Solution

  • I was able to solve my issue by doing this in the song adapter:

            long album_id = cursor.GetLong(cursor.GetColumnIndex(MediaStore.Audio.Albums.InterfaceConsts.AlbumId));
            var songCover = Android.Net.Uri.Parse ("content://media/external/audio/albumart");
            var songAlbumArtUri = ContentUris.WithAppendedId (songCover, album_id);
    
            song_artist.Text = songAlbumArtUri.ToString();
            song_album_art.SetImageURI (songAlbumArtUri);
    

    I found the answer thanks to this stackoverflow answer: Getting album art from the audio file Uri