【问题标题】:Most robust way to fetch album art in Android在 Android 中获取专辑封面的最强大方法
【发布时间】:2011-07-06 02:58:19
【问题描述】:

请注意,我已经在这里和其他网站上遇到过类似的问题及其答案。我还有一个适用于某些设备的解决方案(我的 G2X 运行 CyanogenMod 7.1,我妻子的 HD2 运行自定义 ROM 和模拟器运行 Android 2.1)。但它不适用于运行 CyanogenMod 的 Nook。

我的问题是:在所有 android 设备上获取专辑封面的最强大和最通用的方法是什么?特定设备、版本或音乐应用程序的陷阱是什么(我不是指第三方播放器,我是指 Google 音乐与旧的音乐客户端)?我当前的代码是:

// 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;
    }
}

提前致谢, 阿南特

【问题讨论】:

    标签: java android albumart


    【解决方案1】:

    在这里我可以附加一个从媒体商店返回专辑封面的功能。在函数中,我们只需要传递从媒体商店获得的专辑 ID。

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

    【讨论】:

    • 感谢您的回答,您的代码(和我的)使用的 URI 是否始终有效?即使在没有 SD 卡的设备上?
    • 这里只有当 sdcard 插入设备时才需要 uri。
    • 唯一的缺点是这需要 android.permission.WRITE_EXTERNAL_STORAGE
    【解决方案2】:
    Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
    Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id);
    ContentResolver res = context.getContentResolver();
    InputStream in = res.openInputStream(uri);
    Bitmap artwork = BitmapFactory.decodeStream(in);
    

    更完整的示例代码可以在这里找到Android音乐播放器源代码https://github.com/android/platform_packages_apps_music/blob/master/src/com/android/music/MusicUtils.java方法getArtworkQuick。

    【讨论】:

      【解决方案3】:

      下面的代码 sn-p 返回 MediaStore 中存在的专辑封面缓存的 uri。这可能会有所帮助。

                  Cursor cursorAudio = managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, {MediaStore.Audio.Media.ALBUM_ID, MediaStore.Audio.Media.DATA}, MediaStore.Audio.Media.DATA+ " LIKE \"" + path+ "\"", null, null);if(cursorAudio != null  && cursorAudio.moveToFirst()){
              Long albumId = Long.valueOf(cursorAudio.getString(cursorAudio.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)));
              cursorAudio.close();
              Cursor cursorAlbum = managedQuery(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, {MediaStore.Audio.Albums._ID, MediaStore.Audio.Albums.ALBUM_ART}, MediaStore.Audio.Albums._ID+ "=" + albumId, null, null);
              if(cursorAlbum != null  && cursorAlbum.moveToFirst()){
                  String uri = cursorAlbum.getString(cursorAlbum.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART));
                  cursorAlbum.close();
                  if(uri != null){
                      return Uri.parse(uri);
                  }
              }
      

      【讨论】:

        【解决方案4】:

        我想通过使用 Picasso 库来修改 Chirag Raval 的答案。它使用简单,功能强大。

        final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
            Uri uri = ContentUris.withAppendedId(sArtworkUri, arrayList.get(i).getArt());
            Picasso.with(context).load(uri).placeholder(R.mipmap.ic_launcher).error(R.mipmap.ic_launcher)
                    .into(ivPic);
        

        有关完整文档,请参阅this.

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多