哪个Android类生成音乐专辑缩略图?

时间:2015-05-10 13:05:41

标签: android android-mediascanner

我试图了解android MediaStore / MediaScanner如何创建音乐专辑缩略图。我查看了MediaStore.java和MediaScanner.java来源,但无法找到任何内容。

你们知道我在哪里可以找到相关代码吗?感谢。

1 个答案:

答案 0 :(得分:0)

MediaProvider.java包含用于创建专辑缩略图并将其保存在SD卡中的方法。

https://android.googlesource.com/platform/packages/providers/MediaProvider/+/android-4.4.2_r2/src/com/android/providers/media/MediaProvider.java

private ParcelFileDescriptor makeThumbInternal(ThumbData d) {
    byte[] compressed = getCompressedAlbumArt(getContext(), d.path);
    if (compressed == null) {
        return null;
    }
    Bitmap bm = null;
    boolean need_to_recompress = true;
    try {
        // get the size of the bitmap
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;
        opts.inSampleSize = 1;
        BitmapFactory.decodeByteArray(compressed, 0, compressed.length, opts);
        // request a reasonably sized output image
        final Resources r = getContext().getResources();
        final int maximumThumbSize = r.getDimensionPixelSize(R.dimen.maximum_thumb_size);
        while (opts.outHeight > maximumThumbSize || opts.outWidth > maximumThumbSize) {
            opts.outHeight /= 2;
            opts.outWidth /= 2;
            opts.inSampleSize *= 2;
        }
        if (opts.inSampleSize == 1) {
            // The original album art was of proper size, we won't have to
            // recompress the bitmap later.
            need_to_recompress = false;
        } else {
            // get the image for real now
            opts.inJustDecodeBounds = false;
            opts.inPreferredConfig = Bitmap.Config.RGB_565;
            bm = BitmapFactory.decodeByteArray(compressed, 0, compressed.length, opts);
            if (bm != null && bm.getConfig() == null) {
                Bitmap nbm = bm.copy(Bitmap.Config.RGB_565, false);
                if (nbm != null && nbm != bm) {
                    bm.recycle();
                    bm = nbm;
                }
            }
        }
    } catch (Exception e) {
    }
    if (need_to_recompress && bm == null) {
        return null;
    }
    if (d.albumart_uri == null) {
        // this one doesn't need to be saved (probably a song with an unknown album),
        // so stick it in a memory file and return that
        try {
            return ParcelFileDescriptor.fromData(compressed, "albumthumb");
        } catch (IOException e) {
        }
    } else {
        // This one needs to actually be saved on the sd card.
        // This is wrapped in a transaction because there are various things
        // that could go wrong while generating the thumbnail, and we only want
        // to update the database when all steps succeeded.
        d.db.beginTransaction();
        Uri out = null;
        ParcelFileDescriptor pfd = null;
        try {
            out = getAlbumArtOutputUri(d.helper, d.db, d.album_id, d.albumart_uri);
            if (out != null) {
                writeAlbumArt(need_to_recompress, out, compressed, bm);
                getContext().getContentResolver().notifyChange(MEDIA_URI, null);
                pfd = openFileHelper(out, "r");
                d.db.setTransactionSuccessful();
                return pfd;
            }
        } catch (IOException ex) {
            // do nothing, just return null below
        } catch (UnsupportedOperationException ex) {
            // do nothing, just return null below
        } finally {
            d.db.endTransaction();
            if (bm != null) {
                bm.recycle();
            }
            if (pfd == null && out != null) {
                // Thumbnail was not written successfully, delete the entry that refers to it.
                // Note that this only does something if getAlbumArtOutputUri() reused an
                // existing entry from the database. If a new entry was created, it will
                // have been rolled back as part of backing out the transaction.
                getContext().getContentResolver().delete(out, null, null);
            }
        }
    }
    return null;
}