最近遇到一个问题,就是音乐播放器没法拿到专辑图片,总是报以下错误:java
---SkImageDecoder::Factory returned null
如下为调试的一些思路及解决方法。android
1 public static Bitmap getArtwork(Context context, long song_id, long album_id, 2 boolean allowdefault) { 3 4 if (album_id < 0) { 5 // This is something that is not in the database, so get the album art directly 6 // from the file. 7 if (song_id >= 0) { 8 Bitmap bm = getArtworkFromFile(context, song_id, -1); 9 if (bm != null) { 10 return bm; 11 } 12 } 13 if (allowdefault) { 14 return getDefaultArtwork(context); 15 } 16 return null; 17 } 18 19 ContentResolver res = context.getContentResolver(); 20 Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id); 21 if (uri != null) { 22 InputStream in = null; 23 try { 24 in = res.openInputStream(uri); 25 return BitmapFactory.decodeStream(in, null, sBitmapOptions); 26 } catch (FileNotFoundException ex) { 27 // The album art thumbnail does not actually exist. Maybe the user deleted it, or 28 // maybe it never existed to begin with. 29 Bitmap bm = getArtworkFromFile(context, song_id, album_id); 30 if (bm != null) { 31 if (bm.getConfig() == null) { 32 bm = bm.copy(Bitmap.Config.RGB_565, false); 33 if (bm == null && allowdefault) { 34 return getDefaultArtwork(context); 35 } 36 } 37 } else if (allowdefault) { 38 bm = getDefaultArtwork(context); 39 } 40 return bm; 41 } finally { 42 try { 43 if (in != null) { 44 in.close(); 45 } 46 } catch (IOException ex) { 47 } 48 } 49 } 50 51 return null; 52 }
android/packages/providers/MediaProvider/src/com/android/providers/media/MediaProvider.java
在此文件中有实现openFile函数。数据库
/mnt/sdcard/Android/data/com.android.providers.media/albumthumbs/1263093833711
android/frameworks/base/media/libstagefright/id3/ID3.cpp
文件里的getAlbumArt函数。ide
<Headerfor'Attached picture', ID: "APIC"> Text encoding $xx MIME type <textstring> $00 Picture type $xx Description <textstringaccordingtoencoding> $00 (00) Picture data <binarydata> $00 ISO-8859-1 character set is used => $00 is sync identifier. $01 Unicode character set is used => $00 00 is sync identifier.
mobile.mp3的APIC段的description的encoding为0x01,所以须要2个0x00做为sync identifier。所以在getAlbumArt函数调用StringSize里须要跳过这2个字节:函数
1 static size_t StringSize(const uint8_t *start, uint8_t encoding) { 2 if (encoding == 0x00 || encoding == 0x03) { 3 // ISO 8859-1 or UTF-8 4 return strlen((const char *)start) + 1; 5 } 6 7 // UCS-2 8 size_t n = 0; 9 while (start[n] != '\0' || start[n + 1] != '\0') { 10 n += 2; 11 } 12 13 n += 2; //mark 14 15 return n; 16 }