NextGenHen
NextGenHen

Reputation: 141

Android loadThumbnail Album Artwork (API 29)

I've been attempting to resolve an album artwork issue for a while but with no success as of yet.

Since API 29 the Album Artwork MediaStore field was deprecated (docs).

As per the suggestion on the documentation page I should now be using the loadThumbnail method, which I have been attempting to do. Unfortunately I cannot get the loadThumbnail function to load album artwork, I've only seen it work with images from "MediaStore.Images.Media.EXTERNAL_CONTENT_URI", which does not seem to contain all the albums, nor a method for mapping to them using an ID.

This is my current attempt, which does not seem to be working yet. Has anyone had any success loading album artwork using the new loadThumbnail method? I'm using a Google Pixel 3a for my testing.

Getting the cursor:

    return mContext.getContentResolver().query(
            MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            {
                MediaStore.Audio.Media._ID, MediaStore.Audio.Media.TRACK,
                MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.ALBUM,
                MediaStore.Audio.Media.DURATION, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.YEAR,
                MediaStore.Audio.Media.COMPOSER, MediaStore.Audio.Albums.ALBUM_ID
            },
            MediaStore.Audio.Media._ID + "=?",
            new String[]{String.valueOf(id)},
            null);

Extracting the album id:

cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Albums.ALBUM_ID)),

Building the uri to load the thumbnail:

        Uri contentUri = ContentUris.withAppendedId(
                MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
//                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                albumId
        );

        return resolver.loadThumbnail(contentUri, new Size(640, 480), null);

The error provided:

java.io.FileNotFoundException: No media for album content://media/external/audio/albums/1145137507

Upvotes: 2

Views: 2390

Answers (3)

zer0
zer0

Reputation: 11

try this to get album art:

 val cursor: Cursor? = context.contentResolver.query(
            MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            null,
            null,
            null,
            MediaStore.Audio.Media.TITLE + " ASC"
        )
        cursor?.moveToFirst()
        val cTitle: Int? = cursor?.getColumnIndex(MediaStore.Audio.Media.TITLE)
        val cArtist: Int? = 
             cursor?.getColumnIndex(MediaStore.Audio.Media.ARTIST)
        val cPath: Int? = cursor?.getColumnIndex(MediaStore.Audio.Media.DATA)
        val cAlbum: Int? = cursor?.getColumnIndex(MediaStore.Audio.Media.ALBUM)
        val cAlbumId: Int? = 
             cursor?.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)

        cursor?.let { curs ->
            while (!curs.isAfterLast) {
                val title = cTitle?.let { cursor.getString(it) }
                val artist = cArtist?.let { cursor.getString(it) }
                val path = cPath?.let { cursor.getString(it) }
                val album = cAlbum?.let { cursor.getString(it) }
                val albumId = cAlbumId?.let { cursor.getLong(cAlbumId) }
                var bitmap: Bitmap? = null
                var uri: Uri? = null
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    bitmap = getArtBitmapCover(albumId)
                } else {
                    uri = getArtUriCover(albumId)
                }
                val song = SongStorage(title, path, album, artist, bitmap, uri)
                viewModel.listSong.add(song)
                cursor.moveToNext()
            }
            cursor.close()
        }


  @RequiresApi(Build.VERSION_CODES.Q)
    private fun getArtBitmapCover(albumId: Long?): Bitmap? {
      return try {
       val contentUri = albumId?.let
        {  
             ContentUris.withAppendedId
             (MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, it)
        }
        contentUri?.let 
        { 
             context.contentResolver.
             loadThumbnail(it, Size(300,300), null) 
        }
    } catch (e: Exception) {
        null
    }
}


 private fun getArtUriCover(albumId: Long?): Uri? {
    return try {
        val sArtworkUri: Uri = 
            Uri.parse("content://media/external/audio/albumart")
        val albumArtUri: Uri? = albumId?.let {
            ContentUris.withAppendedId(sArtworkUri, it)
        }
        return albumArtUri
    } catch (e: Exception) {
        null
    }
}

Upvotes: 0

satishprattipati
satishprattipati

Reputation: 19

Get Andriod Studio latest 4.2.x and targetSdkVersion to 30

Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    String[] projection = {MediaStore.Audio.AudioColumns.DATA,
            MediaStore.Audio.AudioColumns.TITLE ,
            MediaStore.Audio.AudioColumns.ALBUM,
            MediaStore.Audio.ArtistColumns.ARTIST,
            MediaStore.Audio.AudioColumns.ALBUM_ID};
    Cursor c = getContentResolver().query(uri, projection, null, null, null);

    if (c != null) {
        while (c.moveToNext()) {
            SongTrack songTracks = new SongTrack();
            MediaItem mediaItem = new MediaItem();
            String path = c.getString(0);   // Retrieve path.
            String name = c.getString(1);   // Retrieve name.
            String album = c.getString(2);  // Retrieve album name.
            String artist = c.getString(3); // Retrieve artist name.
            Long albumID=c.getLong(4);

            songTracks.setSongTitle(name);
            songTracks.setSongFilePath(path);
            songTracks.setAlbumartPath("content://media/external/audio/albumart/"+albumID.toString());
            songTracks.setArtist(artist);
            songTracks.setAlbumName(album); 
  Glide.with(getContext()).load(imgFilePath).placeholder(R.drawable.missed).into(tracksAlbumArt);

Upvotes: 0

NextGenHen
NextGenHen

Reputation: 141

Looks like I've found a solution that works:

Cursor:

Cursor images = resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                    new String[]{MediaStore.Audio.Media.ALBUM_ID},
                    null, null, null);

Column:

long id = images.getLong(images.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));

For getting the bitmap:

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private Bitmap getAlbumArtwork(ContentResolver resolver, long albumId) throws IOException {
    Uri contentUri = ContentUris.withAppendedId(
            MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
            albumId
    );

    return resolver.loadThumbnail(contentUri, new Size(640, 480), null);
}

Upvotes: 4

Related Questions