对Android稍有熟悉的人都知道,Android Media Scanner只对SD卡上的媒体文件进行扫描。其扫描的策略,请参考《Android Media Scanner Process》。假如我们的硬件平台上面没有提供SD卡槽,难道Android就不能进行对媒体文件播放了吗?当然不是的,否则Android系统将不会成为一个完善的Framework。本文结合本人的经验介绍一下,怎样修改多媒体文件的扫描路径。

根据《Android Media Scanner Process》的介绍我们可以知道,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目录不存在,则会创建一个。如果已经存在,则不会有任何动作。

另外怎样触发Media Scanner?根据《Android Media Scanner Process》的介绍,当收到ACTION_BOOT_COMPLETED,ACTION_MEDIA_MOUNTED,ACTION_MEDIA_SCANNER_SCAN_FILE消息的时候才会进行扫描。以前是扫描SD卡,当SD卡mount的时候Android系统会有ACTION_MEDIA_MOUNTED消息通知,Media Scanner开始扫描媒体文件。但是我们的/external目录修改之后,怎样通知Android media scanner扫描呢?一个办法是重启,没有人乐意这样做。另外一个办法是运行menu->dev tools->Media Scan,这样将会进行扫描。目前我还没有让目录修改之后,自动扫描的办法。如果你有好的点子,请你给我留言。

通过以上的步骤,可以在Android的/external目录存放媒体文件,并且被music应用程序播放了。当然还有不完善的地方欢迎各位朋友指正。

补充(于2010-9-20)

研究为什么Android系统会自动调用MediaScaner扫描文件呢?研究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消息上报的。这样也可以实时更新媒体数据。

但是我们上面没有真正的SD卡,而是把一个内存中的目录设定为扩展内存。那么我们将永远不会受到ACTION_MEDIA_MOUNTED消息,所以也不会自动扫描外存储内存中的媒体文件。那么你可能会问:为什么运行menu->dev tools->Media Scan就可以扫描外存储内存中的数据呢?这段代码的实现,在文件Development/src/com/android/development/MediaScannerActivity.java中:
@Override
public void onResume() {
super.onResume();

........

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
........
}

可以看出这里面广播了一个ACTION_MEDIA_MOUNTED消息,这样MediaScannerReceiver将会扫描外存储内存中的媒体文件。

更多相关文章

  1. Android 中的消息传递,详解广播机制
  2. android私有目录直接读取
  3. Android 本地推送消息到通知栏 NotificationManager 、注册Andro
  4. 浅析Android中的消息机制
  5. 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
  6. Android按键消息传播流程(WindowManagerService.java)
  7. android文件缓存,并SD卡创建目录未能解决和bitmap内存溢出解决
  8. android异步图片加载三之handler+线程池+消息队列模式
  9. Android基础分析目录

随机推荐

  1. [牛课习题]判断字符串是否回文及统计回文
  2. 0202-类声明及类的实例化,静态成员与类的
  3. PHP初级变量类型转换与变量和常量的声明
  4. anaconda和pycharm区别是什么?Python学习
  5. SQL2005完整+日志+文件+日志备份和还原策
  6. Linux locate命令
  7. mysql主从+keepalive高可用集群
  8. centos7配置网络信息
  9. 华为摄像机播放视频失败问题排查
  10. PHP面向对象编程