Most robust way to fetch album art in Android

Ani picture Ani · Jul 6, 2011 · Viewed 12k times · Source

Please note that I have already been through similar questions and their answers here and on other websites. I also have a solution that works on some devices (my G2X running CyanogenMod 7.1, my wife's HD2 running a custom ROM and the emulator running Android 2.1). It doesn't, however work on my Nook running CyanogenMod.

My question is: What is the most robust and general way to fetch album art on all android devices? What are the gotchas for specific devices, versions or music applications (I don't mean third-party players, I mean Google Music versus the old Music client)? My current code is:

// Is this what's making my code fail on other devices?
public final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");

// This works, and well on all devices
private int[] getAlbumIds(ContentResolver contentResolver)
{
    List<Integer> result = new ArrayList<Integer>();
    Cursor cursor = contentResolver.query(MediaStore.Audio.Media.getContentUri("external"), new String[]{MediaStore.Audio.Media.ALBUM_ID}, null, null, null);

    if (cursor.moveToFirst())
    {
        do{
            int albumId = cursor.getInt(0);
            if (!result.contains(albumId))
                result.add(albumId);
        } while (cursor.moveToNext());
    }

    int[] resultArray = new int[result.size()];
    for (int i = 0; i < result.size(); i++)
        resultArray[i] = result.get(i);

    return resultArray;
}

// This is the bit I want to make more robust, make sure that it works on all devices
private Shader getAlbumArt(ContentResolver contentResolver, int albumId, int width, int height)
{
    Uri uri = ContentUris.withAppendedId(sArtworkUri, albumId);
    InputStream input = null;
    try {
        input = contentResolver.openInputStream(uri);
        if (input == null)
            return null;

        Bitmap artwork = BitmapFactory.decodeStream(input);
        input.close();
        if (artwork == null)
            return null;

        Bitmap scaled = Bitmap.createScaledBitmap(artwork, width, height, true);
        if (scaled == null)
            return null;

        if (scaled != artwork)
            artwork.recycle();
        artwork = scaled;

        return new BitmapShader(artwork, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

Thanks in advance, Ananth

Answer

Chirag picture Chirag · Jul 6, 2011

Here i can attach one function that is return album art from media store . Here in function we just have to pass the album_id which we get from Media store .

   public Bitmap getAlbumart(Long album_id) 
   {
        Bitmap bm = null;
        try 
        {
            final Uri sArtworkUri = Uri
                .parse("content://media/external/audio/albumart");

            Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id);

            ParcelFileDescriptor pfd = context.getContentResolver()
                .openFileDescriptor(uri, "r");

            if (pfd != null) 
            {
                FileDescriptor fd = pfd.getFileDescriptor();
                bm = BitmapFactory.decodeFileDescriptor(fd);
            }
    } catch (Exception e) {
    }
    return bm;
}