通过前面文章的学习,android media scanner只会对内存和sdcard上的媒体文件进行扫描。
假如我们的硬件平台上面没有提供SD卡槽,可以用usb替换sdcard。通过修改ics,可以设置利用sda*来替换sdcard,当作sdcard去使用。比如tv端如果没有sdcard槽,一般会把第一个插入的usb并且是sda1的磁盘当作sdcard。
我们知道,Android scanner扫描媒体完成之后,会把媒体文件存放在数据库中,由MediaProvider为上层的应用程序提供服务。
经过研究Media scanner的代码发现,他的扫描路径为android.os.Environment.EXTERNAL_STORAGE_DIRECTORY。定义该变量文件位于:
frameworks/base/core/java/android/os/Environment.java
默认情况下,Android将会搜索/sddisk目录:
private static final File EXTERNAL_STORAGE_DIRECTORY = getDirectory("EXTERNAL_STORAGE", "/sddisk");
为了让其进行搜索我们自定义的路径,可以修改该变量的定义,加入我们希望扫描/external目录。代码修改如下:
private static final File EXTERNAL_STORAGE_DIRECTORY = getDirectory("EXTERNAL_STORAGE", "/external");
这样Android Media Scanner将会搜索/external目录来查找媒体文件。
下一步我们需要保证这个文件一定要存在,我们需要修改init.rc文件。增加如下的定义:
mkdir /external 0777 system system
这样在开机的时候,如果/external目录不存在,则会创建一个。如果已经存在,则不会有任何动作。
一般我们不会想去修改sdcard自带的路径,可以按照以上方式,在framework层添加其他路径去扫描。
研究MediaScannerReceiver的源码发现:
@Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Uri uri = intent.getData(); String externalStoragePath = Environment.getExternalStorageDirectory().getPath(); if (action.equals(Intent.ACTION_BOOT_COMPLETED)) { // scan internal storage scan(context, MediaProvider.INTERNAL_VOLUME); } else { if (uri.getScheme().equals("file")) { // handle intents related to external storage String path = uri.getPath(); if (action.equals(Intent.ACTION_MEDIA_MOUNTED) && externalStoragePath.equals(path)) { scan(context, MediaProvider.EXTERNAL_VOLUME); } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE) && path != null && path.startsWith(externalStoragePath + "/")) { scanFile(context, path); } } } }
我们发现在收到ACTION_BOOT_COMPLETED消息时,Android系统会扫描内存中的媒体文件。当系统收到ACTION_MEDIA_MOUNTED才会去扫描系统中的扩展内存(一般是SD卡)。
假如系统中有SD卡的话,系统启动的时候是可以收到ACTION_MEDIA_MOUNTED消息和ACTION_BOOT_COMPLETED消息的,这样开机的时候系统会对系统进行媒体文件扫描。当SD卡文件修改了(比如用数据线,连接PC),一般也是有ACTION_MEDIA_MOUNTED消息上报的。这样也可以实时更新媒体数据。
@Override public void onResume() { super.onResume(); ........ sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); ........ }
可以看出这里面广播了一个ACTION_MEDIA_MOUNTED消息,这样MediaScannerReceiver将会扫描外存储内存中的媒体文件。