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


    下面是系统
      

MediaScannerReceiver会在任何的ACTION_BOOT_COMPLETED, ACTION_MEDIA_MOUNTED ACTION_MEDIA_SCANNER_SCAN_FILE 意图(intent)发出的时候启动。因为解析媒体文件的元数据或许会需要很长时间,所以MediaScannerReceiver会启动MediaScannerService


MediaScannerService调用一个公用类MediaScanner去处理真正的工作。MediaScannerReceiver维持两种扫描目录:一种是内部卷(internal volume)指向$(ANDROID_ROOT)/media. 另一种是外部卷(external volume)指向$(EXTERNAL_STORAGE). 

扫描和解析工作位于JAVA层和C++层。JAVA层是启动器。MediaScanner扫描所有目录,如下步骤:


1.JAVA层初始化


    在这一步骤中,它会根据目录是在内部卷还是外部卷打开不同的数据库


2.Java层预扫描


    首先清除文件和播放列表的缓存条目。然后根据MediaProvider返回的请求结果生成新文件和播放列表缓存条目。


3.C++层处理目录


    列举出所有文件和特定的所有子目录(如果子目录包含一个.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, "p_w_picpath/jpeg"); 
addFileType("JPEG", FILE_TYPE_JPEG, "p_w_picpath/jpeg"); 
addFileType("GIF", FILE_TYPE_GIF, "p_w_picpath/gif"); 
addFileType("PNG", FILE_TYPE_PNG, "p_w_picpath/png"); 
addFileType("BMP", FILE_TYPE_BMP, "p_w_picpath/x-ms-bmp"); 
addFileType("WBMP", FILE_TYPE_WBMP, "p_w_picpath/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层扫描文件

    aJava层开始文件

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

    b)C++层扫描文件

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



 

  1. if (mFileType == MediaFile.FILE_TYPE_MP3 ||
  2. mFileType == MediaFile.FILE_TYPE_MP4 ||
  3. mFileType == MediaFile.FILE_TYPE_M4A ||
  4. mFileType == MediaFile.FILE_TYPE_3GPP ||
  5. mFileType == MediaFile.FILE_TYPE_3GPP2 ||
  6. mFileType == MediaFile.FILE_TYPE_OGG ||
  7. mFileType == MediaFile.FILE_TYPE_MID ||
  8. mFileType == MediaFile.FILE_TYPE_WMA) {
  9. ……

 

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

    c)Java层结束文件

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

5.Java层发送扫描

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

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




原文地址 http://letsgoustc.spaces.live.com/blog/cns!89AD27DFB5E249BA!473.entry?_c=BlogPart

更多相关文章

  1. 三种方法使android 手机执行 二进制程序
  2. Android_判断文件是否存在并创建代码
  3. Android(安卓)pm命令使用方法
  4. Android这可能是当今最火,功能最全的快速开发框架了
  5. 如何制作Jar包并在android中调用jar包
  6. Animations使用 (四)
  7. Android(安卓)VideoView简单播放视频
  8. Android使用ViewPager实现左右滑动效果
  9. NPM 和webpack 的基础使用

随机推荐

  1. Android(安卓)Studio编译release版本
  2. Android截屏实现——亲测有效代码
  3. Eclipse环境下格式化Android的代码风格
  4. android 中的 Handler Thread Runnable
  5. java第四次实验
  6. Android(安卓)ImageView的scaleType属性
  7. Android(安卓)Duplicate files copied in
  8. EditText属性详解
  9. 【Android(安卓)应用开发】 Ubuntu 安装
  10. android 模拟抢红包 原理