SD卡:MediaScannerService与MediaScanner扫描SD卡/启动完成- Android

MediaScannerService研究- https://blog.csdn.net/codefly/article/details/53177926
Android调用MediaScanner进行扫描-  https://bashenmail.iteye.com/blog/603680

 SD卡,MediaScannerService收到media_mount的action;手机存储卡,MediaScannerService收到boot_completed的action. 
 MediaScannerService是Android平台提供的一个用于扫描手机中多媒体文件的应用级service。它并不是系统服务。MediaScannerService和MediaProvider有着非常紧密的关系,因为扫描出的结果总需要存储到某个地方来展现给用户。
public void run() {
    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND +
                              Process.THREAD_PRIORITY_LESS_FAVORABLE);
    Looper.prepare();
    mServiceLooper   = Looper.myLooper();               // 消息looper
    mServiceHandler  = new ServiceHandler();            // 发送消息的handler
    Looper.loop();
}

  -- MediaScanner和媒体文件扫描有关,例如,在Music应用程序中见到的歌曲专辑名、歌曲时长等信息,都是通过它扫描对应的歌曲而得到的。另外,通过MediaStore接口查询媒体数据库,从而得到系统中所有媒体文件的相关信息也和MediaScanner有关,因为数据库的内容就是由MediaScanner添加的。
  MediaScannerService调用一个公用类MediaScanner去处理真正的工作。MediaScannerReceiver维持两种扫描目录:一种是内部卷(internal volume)指向$(ANDROID_ROOT)/media. 另一种是外部卷(external volume)指向$(EXTERNAL_STORAGE). 

  当系统刚刚启动时,收到ACTION_BOOT_COMPLETED广播,此时会把内部卷标(“internal”)和外部卷标(“external”)都扫描一下;
  如果收到ACTION_MEDIA_MOUNTED广播,则只扫描外部卷标;
  如果收到的是ACTION_MEDIA_SCANNER_SCAN_FILE广播,则扫描具体的文件路径。

-- MediaScannerService三个组件:
 1.MediaScannerService(从Service派生)模块负责扫描媒体文件,然后将扫描得到的信息插入到媒体数据库中。
 2.MediaProvider(从ContentProvider派生)模块负责处理针对这些媒体文件的数据库操作请求,例如查询、删除、更新等。
 3.MediaScannerReceiver(从BroadcastReceiver派生)模块负责接收外界发来的扫描请求。也就是MS对外提供的接口。

<receiver android:name="MediaScannerReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.MEDIA_MOUNTED" />
        <data android:scheme="file" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.MEDIA_UNMOUNTED" />
        <data android:scheme="file" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.MEDIA_SCANNER_SCAN_FILE" />
        <data android:scheme="file" />
    </intent-filter>
</receiver>

public void onReceive(Context context, Intent intent) {
    final String action = intent.getAction();
    final Uri uri = intent.getData();
    
    if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
        // Scan both internal and external storage
        scan(context, MediaProvider.INTERNAL_VOLUME);  // INTERNAL_VOLUME = "internal"
        scan(context, MediaProvider.EXTERNAL_VOLUME);  // EXTERNAL_VOLUME = "external"
    } else {
        if (uri.getScheme().equals("file")) {
            // handle intents related to external storage
            . . . . . .
            Log.d(TAG, "action: " + action + " path: " + path);
            if (Intent.ACTION_MEDIA_MOUNTED.equals(action)) {
                // scan whenever any volume is mounted
                scan(context, MediaProvider.EXTERNAL_VOLUME);
            } else if (Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action) &&
                    path != null && path.startsWith(externalStoragePath + "/")) {
                scanFile(context, path);
            }
        }
    }
}

static const char *kValidExtensions[] = {
        ".mp3", ".mp4", ".m4a", ".3gp", ".3gpp", ".3g2", ".3gpp2",
        ".mpeg", ".ogg", ".mid", ".smf", ".imy", ".wma", ".aac",
        ".wav", ".amr", ".midi", ".xmf", ".rtttl", ".rtx", ".ota",
        ".mkv", ".mka", ".webm", ".ts", ".fl", ".flac", ".mxmf",
        ".avi", ".mpeg", ".mpg", ".awb", ".mpga"
    };

-- 使用MediaScannerConnection执行具体文件或文件夹进行扫描,核心代码如下:
try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Intent mediaScanIntent = new Intent(
                    Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            Uri contentUri = Uri.fromFile(Environment.getExternalStorageDirectory()); //指定SD卡路径
            mediaScanIntent.setData(contentUri);
            sendBroadcast(mediaScanIntent);
        } else {
            sendBroadcast(new Intent(
                    Intent.ACTION_MEDIA_MOUNTED,
                    Uri.parse("file://"
                            + Environment.getExternalStorageDirectory())));
                }
  } catch(Exception e) {
        e.getMessage();
  } 
}

猜你喜欢

转载自blog.csdn.net/ShareUs/article/details/90734882
今日推荐