关于媒体文件扫描,我们需要弄明白两个问题:
1.什么时候开启媒体文件扫描
2.如何解析媒体文件(音频,视频,图片)信息插入到数据库中,对应code流程
我们现在音乐,视频播放器,图库等应用关于音视频图片等信息都是通过多媒体数据库直接查询
在源码 packages\providers\下有个叫MediaProvider(进程名:android.process.media)
它主要处理管理这个媒体数据库,处理MTP,铃声选择也在当中.
在MediaProvider中有一个广播接收类MediaScannerReceiver,当中监听以下几个广播:
<action android:name="android.intent.action.BOOT_COMPLETED" /> //开机完成
<action android:name="android.intent.action.MEDIA_MOUNTED" /> //挂载
<action android:name="android.intent.action.MEDIA_UNMOUNTED" /> //卸载
<action android:name="android.intent.action.MEDIA_SCANNER_SCAN_FILE" /> //扫描文件
<action android:name="android.intent.action.ACTION_SHUTDOWN" /> //关机
--------------------------------------------------------------------------------
//以下两个是我司内部加的
<action android:name="android.intent.action.ACTION_SHUTDOWN_IPO" />
<action android:name="android.intent.action.OVERTIME_REMOVAL" /> // 热插拔优化广播
从源码看,会启动扫描动作的是BOOT_COMPLETED(开机),MEDIA_MOUNTED(挂载)
MEDIA_UNMOUNTED(卸载),MEDIA_SCANNER_SCAN_FILE(扫描文件)会执行扫描.
在开机后会执行
scan(context, MediaProvider.INTERNAL_VOLUME); //扫描内部存储
scanUntilAllStorageMounted(context);//挂载大于5秒或者挂载成功后执行
scan(context, MediaProvider.EXTERNAL_VOLUME);//扫描外部存储
private void scan(Context context, String volume) { Bundle args = new Bundle(); args.putString("volume", volume); context.startService( new Intent(context, MediaScannerService.class).putExtras(args));}
启动单个文件扫描
private void scanFile(Context context, String path) { Bundle args = new Bundle(); args.putString(“filepath”, path); context.startService( new Intent(context, MediaScannerService.class).putExtras(args));}
我们可以看到当调用scan(),scanFile()方法,会启动MediaScannerService服务执行扫描
该类继承Service实现Runnable
总结:
MediaScannerReceiver是用来接收任务,它收到广播后,会启动MediaSannerService进行扫描工作。
在MediaScannerService onCreate中开启了线程,Service是跑在主线程的,扫描是个耗时的操作,避免堵塞开启线程
public class MediaScannerService extends Service implements Runnable
Thread thr = new Thread(null, this, "MediaScannerService