转载自:http://blog.csdn.net/qikaibinglan/article/details/6123403

源码android/packages/apps/providers/media/src/com/android/providers/media/MediaScannerReceiver.java

package com.android.providers.media;

import android.content.Context;
import android.content.Intent;
import android.content.BroadcastReceiver;
import android.net.Uri;
import android.os.Environment;
import android.os.Bundle;

import java.io.File;


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

// scan external storage if it is mounted
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
scan(context, MediaProvider.EXTERNAL_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));
}
}


从上面的源码可以总结以下几点:
1,action.equals(Intent.ACTION_BOOT_COMPLETED)
每当机器boot完之后就会发出Intent.ACTION_BOOT_COMPLETED,而在MediaScannerReceiver 接到该Action之后就对Internal 和External(若Sdcard挂载了)扫描,将其数据扫描到对应的数据库。所以你在开发的时候,每次开模拟器或手机你注意Logcat信息,就可以发现:scanner Internal Volumn...等等相关信息

2,uri.getScheme().equals("file")
除了接受机器boot完的Action要去扫描,还接受了以file中的两种扫描:扫描External和扫描一个文件:
1)
action.equals(Intent.ACTION_MEDIA_MOUNTED) &&
externalStoragePath.equals(path)[/color])
scan(context, MediaProvider.EXTERNAL_VOLUME);
2)
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE) &&
path != null[/color] && path.startsWith(externalStoragePath + "/")) {
scanFile(context, path)

我们可以找到android自带ap的里运用了这种,就是Deve Tool里的Media Scanner,其扫描Sdcard:
其源码:apps›Development›src›com›android›development›MediaScannerActivity.java
Java代码
package com.android.development;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.BroadcastReceiver;
import android.net.Uri;
import android.os.Environment;
import android.widget.TextView;

public class MediaScannerActivity extends Activity
{
public MediaScannerActivity() {
}

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

setContentView(R.layout.media_scanner_activity);

[color=red]IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_STARTED);
intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
intentFilter.addDataScheme("file");
registerReceiver(mReceiver, intentFilter)[/color];

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

mTitle = (TextView) findViewById(R.id.title);
mTitle.setText("Sent ACTION_MEDIA_MOUNTED to trigger the Media Scanner.");
}

/** Called when the activity going into the background or being destroyed. */
@Override
public void onPause() {
super.onPause();
unregisterReceiver(mReceiver);
}

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) {
mTitle.setText("Media Scanner started scanning " + intent.getData().getPath());
}
else if (intent.getAction().equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
mTitle.setText("Media Scanner finished scanning " + intent.getData().getPath());
}
}
};

private TextView mTitle;
}

更多相关文章

  1. Socket编程java[简单易懂],附带Android(安卓)Studio 项目聊天实
  2. android cupcake源码编译问题
  3. Android(安卓)Socket编程
  4. Build android source code 2 -- 下载源码
  5. Flutter Android启动源码分析(一)
  6. Android的消息机制源码分析(4)- Handler
  7. android wifi 操作
  8. 使用android隐藏api实现亮度调节
  9. android 扫描SD卡与系统文件

随机推荐

  1. android快速点击生成两个相同页面的解决
  2. Android SDK Permission大全访问权限
  3. Android原生视频播放VideoView的使用
  4. Keep ProgressDialog while rotate the p
  5. 2012-7-17 android:layout_weight
  6. Android 弹框UI框架
  7. C#移动端开发之Xamarin.Forms使用文档(从
  8. 2012年4月6日学习记录
  9. Android横向拼接多个Bitmap
  10. Android功能代码