2014-05-15 47 views
2

我正在尝试获取手机中存在的所有歌曲的专辑封面。我正在使用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

一旦你的相册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; 
} 

您可以通过ID使用像这样(未经)获得地图的所有专辑封面

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; 
} 
+0

感谢马特的答案。我已经在上面发布了我的答案。但是我在创建时在设备上获取了大约300首歌曲的专辑封面,延迟了2-3秒。有什么方法可以加快速度吗? – Siju

+0

是的,你可以在一个查询中得到它们。您可以删除WHERE参数,并遍历所有专辑,获取他们的专辑封面,或使用相册ID构建WHERE IN子句。请记住,如果你要将参数绑定到'?',那么你只限于999个参数。 – Matt

+0

你可以请给我代码如何做到这一点。获取专辑封面需要很长时间。我也试过使用异步任务。但专辑艺术的装载仍然需要时间。 – Siju

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()); 

    } 
+0

工作得很好。谢谢! +1 –

1

进行快速渲染

如果使用recylerview,列表视图来呈现歌曲列表,它是由于从歌曲的路径,那么你可以先获得专辑封面制作慢检查ImageView是否已经设置了背景图像,然后不处理任何东西。即使歌曲列表非常大,它也会减少很多处理并快速滚动。我面临同样的问题。我只是做了同样的提及和recyclerview渲染专辑艺术变得顺利,否则它在滚动期间卡住了。 我是这会帮助别人。

我对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(); 
     } 
    }