获取所有音乐文件的专辑封面

时间:2014-05-15 15:46:01

标签: android android-mediaplayer mediastore

我正在尝试获取手机上所有歌曲的专辑封面。我正在使用MediaStore来获取所有歌曲标题,艺术家等。我该如何获取专辑封面?我尝试使用MediaMetaDataRetriever,但对如何将它用于多个文件感到困惑。有人可以调整这段代码吗?

活动类:

public void getSongList() {
    // retrieve song info
    ContentResolver musicResolver = getContentResolver();
    Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    Cursor musicCursor = musicResolver.query(musicUri, null, null, null,
            null);
    metaRetriver.setDataSource(MainActivity.this,musicUri); // now how to loop over this

    if (musicCursor != null && musicCursor.moveToFirst()) {
        // get columns
        int titleColumn = musicCursor.getColumnIndex(MediaColumns.TITLE);
        int idColumn = musicCursor.getColumnIndex(BaseColumns._ID);
        int artistColumn = musicCursor.getColumnIndex(AudioColumns.ARTIST);

        // add songs to list
        do {
            long thisId = musicCursor.getLong(idColumn);
            String thisTitle = musicCursor.getString(titleColumn);
            String thisArtist = musicCursor.getString(artistColumn);
            songList.add(new Song(thisId, thisTitle, thisArtist));
        } while (musicCursor.moveToNext());

    }

3 个答案:

答案 0 :(得分:3)

如果您拥有可从同一光标获取的相册ID,则可以查询封面艺术路径的其他URI。请参阅下面的示例,了解我如何做到这一点:

private static String getCoverArtPath(Context context, long androidAlbumId) {
    String path = null;
    Cursor c = context.getContentResolver().query(
            MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
            new String[]{MediaStore.Audio.Albums.ALBUM_ART},
            MediaStore.Audio.Albums._ID + "=?",
            new String[]{Long.toString(androidAlbumId)},
            null);
    if (c != null) {
        if (c.moveToFirst()) {
            path = c.getString(0);
        }
        c.close();
    }
    return path;
}

您可以使用类似这样的内容获取所有专辑封面的地图(未经测试)

private static Map<Long, String> getCoverArtPaths(Context context) {
    String HashMap<Long, String> map = new HashMap<Long, String>();
    Cursor c = context.getContentResolver().query(
            MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
            new String[]{MediaStore.Audio.Albums._ID, MediaStore.Audio.Albums.ALBUM_ART},
            null,
            null,
            null);
    if (c != null) {
        for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
            map.add(c.getLong(0), c.getString(1));
        }
        c.close();
    }
    // returns a mapping of Album ID => art file path
    return map;
}

答案 1 :(得分:1)

我让它像这样工作。希望它可以帮助某人:)

 public void getSongList() {
    // retrieve song info

    ContentResolver musicResolver = getContentResolver();
    Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    Cursor musicCursor = musicResolver.query(musicUri, null, null, null,
            null);


    if (musicCursor != null && musicCursor.moveToFirst()) {
        // get columns
        int titleColumn = musicCursor.getColumnIndex(MediaColumns.TITLE);
        int idColumn = musicCursor.getColumnIndex(BaseColumns._ID);
        int artistColumn = musicCursor.getColumnIndex(AudioColumns.ARTIST);
        int column_index = musicCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);

        // add songs to list
        do {
            long thisId = musicCursor.getLong(idColumn);
            String pathId = musicCursor.getString(column_index);
            Log.d(this.getClass().getName(), "path id=" + pathId);

            metaRetriver.setDataSource(pathId);
            try { 
                art = metaRetriver.getEmbeddedPicture();
                Options opt = new Options();
                opt.inSampleSize = 2;
                songImage = BitmapFactory .decodeByteArray(art, 0, art.length,opt);
            }
            catch (Exception e) 
            { imgAlbumArt.setBackgroundColor(Color.GRAY); 
            }

            String thisTitle = musicCursor.getString(titleColumn);
            String thisArtist = musicCursor.getString(artistColumn);
            songList.add(new Song(thisId, thisTitle, thisArtist,songImage));
            //              if(songImage!=null)
            //              {
            //              songImage.recycle();
            //              }
        } while (musicCursor.moveToNext());

    }

答案 2 :(得分:1)

用于快速渲染

如果您正在使用recylerview,listview来渲染歌曲列表,并且由于从歌曲路径获取专辑封面而变慢,那么您可以先检查ImageView是否已经设置了背景图像然后不处理任何内容。即使歌曲列表非常大,它也会减少大量处理并使滚动更快。我遇到了同样的问题。我刚刚提到了同样的事情,并且回收视图渲染与专辑艺术变得流畅,否则它在滚动期间被卡住了。 我会帮助别人。

我的Recyclerview代码:

 @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        try {
            if (holder instanceof MusicAdapter.MusicViewHolder) {
                MusicAdapter.MusicViewHolder vh = (MusicAdapter.MusicViewHolder) holder;
                vh.tvTitle.setText(musicList.get(position).title.toString());
                vh.tvArtistAndAblum.setText(musicList.get(position).artist.toString() + " | " + musicList.get(position).album.toString());
                Drawable background = vh.ivMusicIcon.getBackground();
                if(background == null) {
                    String pathId = musicList.get(position).path;
                    MediaMetadataRetriever metaRetriver = new MediaMetadataRetriever();
                    metaRetriver.setDataSource(pathId);
                    try {
                        byte[] art = metaRetriver.getEmbeddedPicture();
                        BitmapFactory.Options opt = new BitmapFactory.Options();
                        opt.inSampleSize = 2;
                        Bitmap songImage = BitmapFactory.decodeByteArray(art, 0, art.length,opt);
                        BitmapDrawable ob = new BitmapDrawable(context.getResources(), songImage);
                        vh.ivMusicIcon.setBackground(ob);
                    }
                    catch (Exception e)
                    {
                        vh.ivMusicIcon.setImageResource(R.drawable.compact_disc);
                    }

                }

            } else if (holder instanceof FooterViewHolder) {
                FooterViewHolder vh = (FooterViewHolder) holder;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }