音乐播放器是从MediaProvider中获取音乐和音乐信息的,在插入SD卡后,MediaProvider启动扫描服务,文件解析通过opencore操作,扫描到的媒体文件由MediaProvider来保存到数据库,数据库位于
/data/data/com.android.providers.media/databases/external-*.db
?
?
在扫描时,扫描到的专辑图片存放于
Android/data/com.android.providers.media/albumthumbs/
?
?
专辑图片选用优先选择音乐内嵌专辑图片
?
如果音乐没有内嵌专辑图片,则在音乐目录下搜索(忽略根目录和下载目录)
?
???????????? 0 AlbumArt.jpg
???????????? 1 AlbumArt*Large.jpg
???????????? 2 Any other jpg image with 'albumart' anywhere in the name
???????????? 3 Any other jpg image
???????????? 4 any other png image
?
?
对于扫描的过程,详细可分析文件:
/android-2.2/packages/providers/MediaProvider/src/com/android/providers/media/MediaProvider.java
?
?
?
?private ParcelFileDescriptor makeThumbInternal(ThumbData d)?---> getCompressedAlbumArt(getContext(), d.path);
?
?
?
如果音频文件中有专辑图片,用音频里的图片,如果没有,则按如下策略选择图片。????
??? // Extract compressed image data from the audio file itself or, if that fails,
??? // look for a file "AlbumArt.jpg" in the containing directory.
??? private static byte[] getCompressedAlbumArt(Context context, String path) {
??????? byte[] compressed = null;
??????? try {
??????????? File f = new File(path);
??????????? ParcelFileDescriptor pfd = ParcelFileDescriptor.open(f,
??????????????????? ParcelFileDescriptor.MODE_READ_ONLY);
??????????? MediaScanner scanner = new MediaScanner(context);
??????????? compressed = scanner.extractAlbumArt(pfd.getFileDescriptor());
??????????? pfd.close();
??????????? // If no embedded art exists, look for a suitable image file in the
??????????? // same directory as the media file, except if that directory is
??????????? // is the root directory of the sd card or the download directory.
??????????? // We look for, in order of preference:
??????????? // 0 AlbumArt.jpg
??????????? // 1 AlbumArt*Large.jpg
??????????? // 2 Any other jpg image with 'albumart' anywhere in the name
??????????? // 3 Any other jpg image
??????????? // 4 any other png image
???????????
??????????? if (compressed == null && path != null) {
??????????????? int lastSlash = path.lastIndexOf('/');
??????????????? if (lastSlash > 0) {
??????????????????? String artPath = path.substring(0, lastSlash);
??????????????????? String sdroot = Environment.getExternalStorageDirectory().getAbsolutePath();
??????????????????? String dwndir = Environment.getExternalStoragePublicDirectory(
??????????????????????????? Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
??????????????????? String bestmatch = null;
??????????????????? synchronized (sFolderArtMap) {
??????????????????????? if (sFolderArtMap.containsKey(artPath)) {
??????????????????????????? bestmatch = sFolderArtMap.get(artPath);
??????????????????????? } else if (!artPath.equalsIgnoreCase(sdroot) &&
??????????????????????????????? !artPath.equalsIgnoreCase(dwndir)) {
??????????????????????????? File dir = new File(artPath);
??????????????????????????? String [] entrynames = dir.list();
??????????????????????????? if (entrynames == null) {
??????????????????????????????? return null;
??????????????????????????? }
??????????????????????????? bestmatch = null;
??????????????????????????? int matchlevel = 1000;
??????????????????????????? for (int i = entrynames.length - 1; i >=0; i--) {
??????????????????????????????? String entry = entrynames[i].toLowerCase();
??????????????????????????????? if (entry.equals("albumart.jpg")) {
??????????????????????????????????? bestmatch = entrynames[i];
??????????????????????????????????? break;
??????????????????????????????? } else if (entry.startsWith("albumart")
??????????????????????????????????????? && entry.endsWith("large.jpg")
??????????????????????????????????????? && matchlevel > 1) {
??????????????????????????????????? bestmatch = entrynames[i];
??????????????????????????????????? matchlevel = 1;
??????????????????????????????? } else if (entry.contains("albumart")
??????????????????????????????????????? && entry.endsWith(".jpg")
??????????????????????????????????????? && matchlevel > 2) {
??????????????????????????????????? bestmatch = entrynames[i];
??????????????????????????????????? matchlevel = 2;
??????????????????????????????? } else if (entry.endsWith(".jpg") && matchlevel > 3) {
??????????????????????????????????? bestmatch = entrynames[i];
??????????????????????????????????? matchlevel = 3;
??????????????????????????????? } else if (entry.endsWith(".png") && matchlevel > 4) {
??????????????????????????????????? bestmatch = entrynames[i];
??????????????????????????????????? matchlevel = 4;
??????????????????????????????? }
??????????????????????????? }
??????????????????????????? // note that this may insert null if no album art was found
??????????????????????????? sFolderArtMap.put(artPath, bestmatch);
??????????????????????? }
??????????????????? }
??????????????????? if (bestmatch != null) {
??????????????????????? File file = new File(artPath, bestmatch);
??????????????????????? if (file.exists()) {
??????????????????????????? compressed = new byte[(int)file.length()];
??????????????????????????? FileInputStream stream = null;
??????????????????????????? try {
??????????????????????????????? stream = new FileInputStream(file);
??????????????????????????????? stream.read(compressed);
??????????????????????????? } catch (IOException ex) {
??????????????????????????????? compressed = null;
??????????????????????????? } finally {
??????????????????????????????? if (stream != null) {
??????????????????????????????????? stream.close();
??????????????????????????????? }
??????????????????????????? }
??????????????????????? }
??????????????????? }
??????????????? }
??????????? }
??????? } catch (IOException e) {
??????? }
??????? return compressed;
??? }