android中的MediaScanner,MediaStore与MediaProvider

Android系统提供了对多媒体(图片、音乐、视频等)的统一处理机制,通过一套良好的框架实现了多媒体信息的扫描、存储、读取。用户可以基于这套框架非常方便的对多媒体信息进行处理。显儿易见这套框架主要包含了三部分:
MediaScannerService(多媒体扫描服务)
MediaStore(多媒体存储)
MediaProvider(多媒体内容提供者)

那么它们是如何工作的呢,如何对设备上的多媒体进行扫描?如何将多媒体信息进行存储?用户如何读取、修改多媒体信息?这些是我主要想搞清楚的问题。

1.如何调用 MediaScannerService?
android dev tools调用MediaScannerService进行信息扫描的源码:
public class MediaScannerActivity extends Activity{

public MediaScannerActivity() {
}

/** Called when the activity is first created or resumed. */
@Override
public void onResume() {
super.onResume();
......

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"
+ Environment.getExternalStorageDirectory())));
......
}
}
通过源码可以知道,仅仅发送了一个广播(传递对应的扫描要求),那么可以猜测系统肯定存在一个广播接收器(何时何地注册?),在收到这个广播消息后,通过对应参数启动MediaScannerService。
/mydroid/packages/providers/MediaProvider/src/com/android/providers/media/MediaScannerReceiver.java
public class MediaScannerReceiver extends BroadcastReceiver
{
private final static String TAG = "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);
}
}
}
}

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));
}
}

2.MediaScannerService 如何工作?
/mydroid/packages/providers/MediaProvider/src/com/android/providers/media/MediaScannerService.java
MediaScannerService调用一个公用类MediaScanner去处理真正的工作。MediaScannerReceiver维持两种扫描目录:一种是内部卷(internal volume)指向$(ANDROID_ROOT)/media. 另一种是外部卷(external volume)指向$(EXTERNAL_STORAGE).

你可能感兴趣的:(Android)