最近遇到一個問題,就是音樂播放器沒法拿到專輯圖片,總是報以下錯誤: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 }