Android中扫描多媒体文件操作详解
这篇文章从系统源代码分析,讲述如何将程序创建的多媒体文件加入系统的媒体库,如何从媒体库删除,以及大多数程序开发者经常遇到的无法添加到媒体库的问题等。本人将通过对源代码的分析,一一解释这些问题。
Android中的多媒体文件扫描机制
Android提供了一个很棒的程序来处理将多媒体文件加入的媒体库中。这个程序就是MediaProvider,现在我们简单看以下这个程序。首先看一下它的Receiver
<receiverandroid:name="MediaScannerReceiver"> <intent-filter> <actionandroid:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> <intent-filter> <actionandroid:name="android.intent.action.MEDIA_MOUNTED"/> <dataandroid:scheme="file"/> </intent-filter> <intent-filter> <actionandroid:name="android.intent.action.MEDIA_UNMOUNTED"/> <dataandroid:scheme="file"/> </intent-filter> <intent-filter> <actionandroid:name="android.intent.action.MEDIA_SCANNER_SCAN_FILE"/> <dataandroid:scheme="file"/> </intent-filter> </receiver>
MediaScannerReceiver只接收符合action和数据规则正确的intent。
MediaScannerReciever如何处理Intent
1.当且仅当接收到actionandroid.intent.action.BOOT_COMPLETED才扫描内部存储(非内置和外置sdcard)
2.除了action为android.intent.action.BOOT_COMPLETED的以外的intent都必须要有数据传递。
3.当收到Intent.ACTION_MEDIA_MOUNTEDintent,扫描Sdcard
4.当收到Intent.ACTION_MEDIA_SCANNER_SCAN_FILEintent,检测没有问题,将扫描单个文件。
MediaScannerService如何工作
实际上MediaScannerReceiver并不是真正处理扫描工作,它会启动一个叫做MediaScannerService的服务。我们继续看MediaProvider的manifest中关于service的部分。
<serviceandroid:name="MediaScannerService"android:exported="true"> <intent-filter> <actionandroid:name="android.media.IMediaScannerService"/> </intent-filter> </service>
MediaScannerService中的scanFile方法
privateUriscanFile(Stringpath,StringmimeType){ StringvolumeName=MediaProvider.EXTERNAL_VOLUME; openDatabase(volumeName); MediaScannerscanner=createMediaScanner(); returnscanner.scanSingleFile(path,volumeName,mimeType); }
MediaScannerService中的scan方法
privatevoidscan(String[]directories,StringvolumeName){ //don'tsleepwhilescanning mWakeLock.acquire();
ContentValuesvalues=newContentValues(); values.put(MediaStore.MEDIA_SCANNER_VOLUME,volumeName); UriscanUri=getContentResolver().insert(MediaStore.getMediaScannerUri(),values);
Uriuri=Uri.parse("file://"+directories[0]); sendBroadcast(newIntent(Intent.ACTION_MEDIA_SCANNER_STARTED,uri));
try{ if(volumeName.equals(MediaProvider.EXTERNAL_VOLUME)){ openDatabase(volumeName); }
MediaScannerscanner=createMediaScanner(); scanner.scanDirectories(directories,volumeName); }catch(Exceptione){ Log.e(TAG,"exceptioninMediaScanner.scan()",e); }
getContentResolver().delete(scanUri,null,null);
sendBroadcast(newIntent(Intent.ACTION_MEDIA_SCANNER_FINISHED,uri)); mWakeLock.release(); }