Android 多媒体扫描过程(Android Media Scanner Process)

[First written by Steve Guo, please keep the mark if forwarding.]

原作者:Steve Gou 转载请注明!  

 

Here is the overall picture.
下面是系统图
      

MediaScannerReceiver is started when any ACTION_BOOT_COMPLETED, ACTION_MEDIA_MOUNTED or ACTION_MEDIA_SCANNER_SCAN_FILE intent is sent out. Because it may cost a lot of time to parse meta-data information of media files, MediaScannerReceiver will start MediaScannerService. MediaScannerService calls a utility class MediaScanner to do the real work. MediaScannerReceiver maintains two kinds of scan directories: One is internal volume which points to $(ANDROID_ROOT)/media. Another is external volume which points to $(EXTERNAL_STORAGE).

MediaScannerReceiver会在任何的ACTION_BOOT_COMPLETED, ACTION_MEDIA_MOUNTED ACTION_MEDIA_SCANNER_SCAN_FILE 意图(intent)发出的时候启动。因为解析媒体文件的元数据或许会需要很长时间,所以MediaScannerReceiver会启动MediaScannerServiceMediaScannerService调用一个公用类MediaScanner去处理真正的工作。MediaScannerReceiver维持两种扫描目录:一种是内部卷(internal volume)指向$(ANDROID_ROOT)/media. 另一种是外部卷(external volume)指向$(EXTERNAL_STORAGE). 

 

The scan and parse work lies in both JAVA and C++ layer. JAVA layer is the starter. To scan the whole directory, MediaScanner does the following steps.
扫描和解析工作位于JAVA层和C++层。JAVA层是启动器。MediaScanner扫描所有目录,如下步骤:

1. JAVA layer initialize

1.JAVA 层初始化

   In this step, it will open different database according to whether the dir is internal or external volume.
     在这一步骤中,它会根据目录是在内部卷还是外部卷打开不同的数据库。

2.JAVA layer prescan
2.Java 层预扫描

    It first clears file and play list cache entries, then generates new file and play list cache entries according to query result from MediaProvider.
    首先清除文件和播放列表的缓存条目。然后根据MediaProvider返回的请求结果生成新文件和播放列表缓存条目。

3. C++ layer processDirectory
3.C++层处理目录

    It enumerates all files and sub-dirs in a specific dir(If a sub-dir contains a .nomedia hidden file, it won’t be enumerated.). For each enumerated file, it judges whether the file is supported according to file extension. If the file extension is supported, then C++ layer will call back to JAVA layer scanFile. The file extension which will be scanned is listed in MediaFile.java. Here is the list.
    列举出所有文件和特定的所有子目录(如果子目录包含一个.nomedia隐藏文件,则不会被列举出来。)。被列举的文件是根据文件扩展来判断文件是否被支持。如果支持这种文件扩展,C++层就会回调到JAVA层扫描文件。这种扩展就会被扫描到MediaFile.java中列出。下面是支持的文件扩展列表。


/* Audio */ 
addFileType("MP3", FILE_TYPE_MP3, "audio/mpeg"); 
addFileType("M4A", FILE_TYPE_M4A, "audio/mp4"); 
addFileType("WAV", FILE_TYPE_WAV, "audio/x-wav"); 
addFileType("AMR", FILE_TYPE_AMR, "audio/amr"); 
addFileType("AWB", FILE_TYPE_AWB, "audio/amr-wb"); 
addFileType("WMA", FILE_TYPE_WMA, "audio/x-ms-wma"); 
addFileType("OGG", FILE_TYPE_OGG, "application/ogg"); 
addFileType("MID", FILE_TYPE_MID, "audio/midi"); 
addFileType("XMF", FILE_TYPE_MID, "audio/midi"); 
addFileType("RTTTL", FILE_TYPE_MID, "audio/midi"); 
addFileType("SMF", FILE_TYPE_SMF, "audio/sp-midi"); 
addFileType("IMY", FILE_TYPE_IMY, "audio/imelody"); 

/* Video */ 
addFileType("MP4", FILE_TYPE_MP4, "video/mp4"); 
addFileType("M4V", FILE_TYPE_M4V, "video/mp4"); 
addFileType("3GP", FILE_TYPE_3GPP, "video/3gpp"); 
addFileType("3GPP", FILE_TYPE_3GPP, "video/3gpp"); 
addFileType("3G2", FILE_TYPE_3GPP2, "video/3gpp2"); 
addFileType("3GPP2", FILE_TYPE_3GPP2, "video/3gpp2"); 
addFileType("WMV", FILE_TYPE_WMV, "video/x-ms-wmv"); 

/* Image */ 
addFileType("JPG", FILE_TYPE_JPEG, "image/jpeg"); 
addFileType("JPEG", FILE_TYPE_JPEG, "image/jpeg"); 
addFileType("GIF", FILE_TYPE_GIF, "image/gif"); 
addFileType("PNG", FILE_TYPE_PNG, "image/png"); 
addFileType("BMP", FILE_TYPE_BMP, "image/x-ms-bmp"); 
addFileType("WBMP", FILE_TYPE_WBMP, "image/vnd.wap.wbmp"); 

/* Audio Play List */ 
addFileType("M3U", FILE_TYPE_M3U, "audio/x-mpegurl"); 
addFileType("PLS", FILE_TYPE_PLS, "audio/x-scpls"); 
addFileType("WPL", FILE_TYPE_WPL, "application/vnd.ms-wpl"); 


4. JAVA layer scanFile

4.Java层扫描文件


  a) JAVA layer beginFile

    aJava层开始文件


 First it ignores some special files for MacOS and Windows Media Player. Then it looks whether the file has been in the cache entry, if so, it will check whether the file’s last modification time is changed. Finally it returns the result whether the file needs to be processed further. If no need, the following two steps won’t be executed.

首先它忽略一些MacOS  Windows Media Player特殊的文件。然后它会查看被扫描的文件是否已经存在于缓存条目中,如果存在,它会检查文件上次修改的时间是否改变。最后它返回该文件是否需要进一步处理的结果。如果不需要,接下来的两步不会执行。



  b) C++ layer scanFile

    b)C++层扫描文件



Not all the files will be delivered to let C++ layer parse meta-data. Only the following file types will be parsed. Pay attention here, image files are not handled here.

不是所有的文件都需要交给C++层解析成元数据。只有下面的文件类型会被解析,注意,这里不处理image文件。




    • if (mFileType == MediaFile.FILE_TYPE_MP3 || 
    • mFileType == MediaFile.FILE_TYPE_MP4 || 
    • mFileType == MediaFile.FILE_TYPE_M4A || 
    • mFileType == MediaFile.FILE_TYPE_3GPP || 
    • mFileType == MediaFile.FILE_TYPE_3GPP2 || 
    • mFileType == MediaFile.FILE_TYPE_OGG || 
    • mFileType == MediaFile.FILE_TYPE_MID || 
    • mFileType == MediaFile.FILE_TYPE_WMA) { 
    • ……
For each parsed meta-data information, C++ layer will call back to JAVA layer handleStringTag. JAVA layer will record the name/value information.

对于被解析的元数据信息,C++层会回调到JAVA层的handleStringTagJava层会记录它的name/value信息。

 

  c) JAVA layer endFile

    c)Java层结束文件


    Finally JAVA layer updates the corresponding database table provided by MeidaProvider according to the values parsed at        the previous step.

 

   最后根据上一步解析出的值, Java层会更新相应的MeidaProvider产生的数据库表。


5. JAVA layer postScan

5.Java层发送扫描


    Until now, all the files have been scanned, it finally checks the file and play list cache entry to see whether all items still existed in the file system. If have any empty entry, then delete it from database. So that it can keep some kinds of consistence between database and file system.

    到目前为止,所有文件已经被扫描,它最后会检查文件和播放列表缓存条目,看是否所有项仍然存在于文件系统。如果有空条目,则会从数据库中删除。这样它能够保持数据库和文件系统的一致性。


    Other application can know when the scan operation starts and ends through receiving ACTION_MEDIA_SCANNER_STARTED and ACTION_MEDIA_SCANNER_FINISHED intents sent from MediaScannerService.

    其他的应用程序通过接收MediaScannerService发出的ACTION_MEDIA_SCANNER_STARTED ACTION_MEDIA_SCANNER_FINISHED意图能够知道什么时候扫描操作开始和结束。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值