简介

本文是《深入Android媒体存储服务》系列第二篇,简要介绍媒体存储服务扫描文件的流程。文中介绍的是 Android 4.2。

Android 有一套媒体存储服务,进程名是 android.process.media,主要负责把磁盘中的文件信息保存到数据库当中,供其他 APP 使用以及 MTP 模式使用。因此如何保持数据库和磁盘文件保持一致非常关键,这个就是媒体存储服务中 MediaScanner 的工作。

媒体文件扫描流程

整个流程如下图所示,

监听 Intent 事件

MediaProvider(源码位于 packages/providers/MediaProvider)里面的 MediaScannerReceiver 类会监听 Intent 事件,有以下 Intent 时会开始扫描磁盘文件的操作:

Intent 监听表
Intent 动作
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE APP 发出的,扫描单个指定文件
Intent.ACTION_MEDIA_MOUNTED 系统发出的磁盘挂载完成通知,或者是 APP 发出,会执行全磁盘扫描
Intent.ACTION_BOOT_COMPLETED 系统发出的开机启动完成通知,会执行全磁盘扫描,也会扫描 /system/media 目录的媒体文件。

Note: 手机 /system/media 目录下有一些内置媒体文件,例如说系统内置铃声。这个目录只有开机会扫描一次。

开始文件扫描

  1. 以全磁盘扫描为例,接着 MediaProvider 里面的 MediaScannerService 服务启动,开始调用 MediaScanner(frameworks/base/media/java/android/media/MediaScanner.java) 扫描磁盘。MediaScanner 控制整个扫描流程,会通过 JNI 调用相应 C++ 代码遍历整个磁盘的目录树,并调用 libstagefright 多媒体框架分析音乐、图片、视频文件的媒体信息(分辨率、艺术家之类)。
  2. 扫描首先从 prescan 开始,从 MediaProvider 读取所有文件信息,然后检查文件是否还存在磁盘中,不存在的文件从数据库中删除。
  3. 接着遍历目录,当找到一个文件后,会查询 MediaProvider 数据库看文件是否存在,不存在的需要插入;已存在的对比文件修改时间与数据库里面的值是否一致,不一致的需要更新数据库。
  4. 再接着根据后缀名区分文件类型,普通文件直接插入数据库,音视频及图片文件需要调用媒体解析器获取媒体信息。
  5. 然后就可以把该文件的记录插入 MediaProvider 数据库,或者更新已修改文件的数据库记录。这样逐个文件分析,知道遍历完所有文件。

Note: 数据库操作比较费 IO 资源,所以数据库插入、更新、删除操作其实都是批量处理的,操作先进入一个队列,数目达到一定程度才会真正进行数据库操作。

缩略图与专辑封面

APP 通过以下接口查询视频图片缩略图与音乐专辑封面:

 // 查询视频和图片缩略图
MediaStore.Video.Thumbnails.getThumbnail(cr, id, MINI_KIND); // 查询音乐专辑封面
ContentResolver().openFileDescriptor(uri, "r");

第一次取的时候会解析文件取得缩略图或专辑封面,然后缩略图会被缓存到磁盘,数据库也会记录。下次再取时,就会直接返回缓存过的图片,不用去解析文件。

以上简要介绍了媒体存储服务扫描流程,需要深入了解的还是要看相应代码。

转载请注明出处:http://www.cnblogs.com/imouto/p/media-file-scanning-process.html

本文外部镜像:http://oteku.blogspot.com/2013/10/media-file-scanning-process.html

最新文章

  1. 第 22 章 CSS3 渐变效果
  2. 第二章 部署war包到tomcat
  3. ASP.NET Identity 3.0教程
  4. 如何解决""No boot device available(无可用的引导设备)”错误
  5. XML团队介绍发布!
  6. 创建类模式(四):原型(Prototype)
  7. Oracle 关于事物的描述
  8. 最全java的读写操作(转载)
  9. 【百度之星2014~初赛(第二轮)解题报告】Chess
  10. 怎么写cookie
  11. 第二篇、vlc-android之源码介绍
  12. ArrayList如何扩容?
  13. SSH无法连接到服务器
  14. select 详解
  15. nginx 屏蔽恶意请求
  16. windows tomcat web应用以及eclipse console乱码解决方法
  17. 53. Maximum Subarray最大求和子数组12 3(dp)
  18. Jmeter If Controller中设置多个条件用“与”进行连接
  19. 回去看linux的指令1
  20. OFBiz实战(1):整合Groovy+FreeMaker

热门文章

  1. Spring-----3、Spring的核心机制(依赖注入)
  2. git工作区和暂存区
  3. sql update小结
  4. 关于ThinkPHP下使用Uploadify插件 仅有火狐提示HTTP Error (302)错误的解决办法
  5. 05-0. 求序列前N项和(15)
  6. Buffer Cache(缓冲区缓存)篇:keep缓冲区池(保留池)
  7. HTML界面JQuery ajax 返回200,但走Error方法
  8. iOS多线程的基本使用
  9. C# Log4Net使用指南(转)
  10. 浅谈C中的指针和数组(四)