追求幸福 发表于 2013-1-28 18:59:30

MediaScannerReceiver

源码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))
                  scan(context, MediaProvider.EXTERNAL_VOLUME);
2)
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE) &&
                        path != null && path.startsWith(externalStoragePath + "/")) {
                  scanFile(context, path)

我们可以找到android自带ap的里运用了这种,就是Deve Tool里的Media Scanner,其扫描Sdcard:
其源码:apps›Development›src›com›android›development›MediaScannerActivity.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);      IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_STARTED);      intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);      intentFilter.addDataScheme("file");      registerReceiver(mReceiver, intentFilter);      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]
查看完整版本: MediaScannerReceiver