`

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)[/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
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 楼 gryphone 2010-06-14  
LZ 你有尝试过通过Broadcast直接调用系统的MediaScanner么?
所以有这样 在开发多媒体之前 先扫描一下 如此 新加媒体能够被发现

我尝试如下调用之:

public void scan(){
    	Intent i = new Intent();
    	i.setAction("android.intent.action.MEDIA_SCANNER_SCAN_FILE");
    	
    	i.setData(Uri.parse("file:///sdcard/DCIM"));
    	this.sendBroadcast(i);
    }


可惜的是:其无反应 因为我在执行前新加媒体文件 但是MediaStore查询结果并没有变化

不知何故 LZ 我的想法合理么?

相关推荐

    Android媒体库框架(mediascanner).doc

    MediaScannerReceiver 是一个广播接收器,负责接收 ACTION_MEDIA_MOUNTED、ACTION_MEDIA_SCANNER_SCAN_FILE 等广播消息,并启动 MediaScannerService。MediaScannerReceiver 维持两种扫描目录:内部卷(internal ...

    Android_MediaScanner__详尽分析

    首先,MediaScanner服务主要由MediaProvider和MediaScannerReceiver两个组件构成。MediaProvider是一个内容提供者(Content Provider),负责提供媒体文件的数据给需要的客户端应用程序。MediaProvider的实现文件...

    android MediaProvider和MediaScanner详解

    MediaScannerReceiver是一个继承自BroadcastReceiver的组件,用于监听特定的Intent,如开机完成(ACTION_BOOT_COMPLETED)、媒体挂载(ACTION_MEDIA_MOUNTED)和扫描文件(ACTION_MEDIA_SCANNER_SCAN_FILE)。...

    安卓实现多媒体扫描.docx

    1. **MediaScannerReceiver**:此组件负责监听特定的广播事件,例如设备启动完成 (`ACTION_BOOT_COMPLETED`)、存储介质挂载 (`ACTION_MEDIA_MOUNTED`) 或者需要扫描特定文件 (`ACTION_MEDIA_SCANNER_SCAN_FILE`)。...

    Android多媒体扫描过程[参考].pdf

    当系统接收到ACTION_BOOT_COMPLETED、ACTION_MEDIA_MOUNTED或ACTION_MEDIA_SCANNER_SCAN_FILE广播意图时,MediaScannerReceiver会被激活。这些意图通常发生在设备启动完毕、外部存储设备连接或有新文件添加时。...

    Android多媒体扫描过程.pdf

    2. **MediaScannerReceiver**: - 这是接收上述意图的广播接收器,当接收到相关事件时,它会启动MediaScannerService。 3. **MediaScannerService**: - MediaScannerService是处理实际扫描任务的服务,它调用...

    android mediaScannder框架介绍

    当设备启动、媒体设备挂载或接收到特定广播意图时,MediaScannerReceiver会被触发,进而启动MediaScannerService。这个过程确保了新添加或修改的媒体文件能够被系统识别,并更新到媒体库中。 MediaScannerService的...

    Android中扫描多媒体文件操作详解

    Android的多媒体文件扫描机制主要由两个组件组成:`MediaScannerReceiver` 和 `MediaScannerService`。`MediaScannerReceiver` 是一个广播接收器,负责监听特定的意图(Intent)并触发相应的扫描行为。在Android的...

    Mediaprovider简介

    Mediaprovider的简单说明。 MediaProvider包括五个类: ...com.android.providers.media.MediaScannerReceiver com.android.providers.media.MediaScannerService com.android.providers.media.MediaThumbRequest

Global site tag (gtag.js) - Google Analytics