这儿说一下怎么样在自己的应用程序调用系统提供的接口完成对指定媒体文件的扫描,约定:
指定的文件:就是指定路径的文件(filepath);
扫描:获取媒体的详细信息,比如一首歌曲的歌手名、时长、专辑名等。
先看一下简单的做法:
MediaScannerConnection.scanFile(mContext, new String[]{lastPath}, null,new MediaScanCompletedListener(){
? ?@Override
? ?public void onScanCompleted(String path, Uri uri) {
? ?
? ?}
? });
存在的问题:如果在一次调用sacnfile未结束的话,结束当前对象,没办法关闭回调接口,再者,使用不灵活,再次基础上参考系统媒体库,对这个调用进行重写,如下:
一、指定扫描:
下面是我用到的方法,供参考:
import android.content.Context;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.media.MediaScannerConnection.OnScanCompletedListener;
import android.net.Uri;
public class MediaScannerFile {
?
?/**
? * 扫描指定的文件
? *
? * @param context
? * @param filePath
? * @param sListener
? */
?public static MediaScannerConnection scanFile(Context context, String[] filePath, String[] mineType,
? ?OnScanCompletedListener sListener) {
? ClientProxy client = new ClientProxy(filePath, mineType, sListener);
? try {
? ?MediaScannerConnection?connection = new MediaScannerConnection(
? ? ? context.getApplicationContext(), client);
? ?client.mConnection = connection;
? ?connection.connect();
? ?return connection;
? } catch (Exception e) {
? ?e.printStackTrace();
? }
? return null;
?}
?static class ClientProxy implements MediaScannerConnectionClient {
? final String[] mPaths;
? final String[] mMimeTypes;
? final OnScanCompletedListener mClient;
? MediaScannerConnection mConnection;
? int mNextPath;
? ClientProxy(String[] paths, String[] mimeTypes,
? ? OnScanCompletedListener client) {
? ?mPaths = paths;
? ?mMimeTypes = mimeTypes;
? ?mClient = client;
? }
? public void onMediaScannerConnected() {
? ?scanNextPath();
? }
? public void onScanCompleted(String path, Uri uri) {
? ?if (mClient != null) {
? ? mClient.onScanCompleted(path, uri);
? ?}
? ?scanNextPath();
? }
? /**
? * 自动扫描下一个
? */
? void scanNextPath() {
? ?if (mNextPath >= mPaths.length) {
? ? mConnection.disconnect();
? ? return;
? ?}
? ?String mimeType = mMimeTypes != null ? mMimeTypes[mNextPath] : null;
? ?mConnection.scanFile(mPaths[mNextPath], mimeType);
? ?mNextPath++;
? }
?}
}
调用:
if (null != mMediaScannerFile) {
? ? ?mMediaScannerFile.scanFile(mContext, musicFilePaths, null,
? ? ? ?this);
? ? }
这里也可以传递一个文件夹进去:
public void scanAllFile() {
? String[] rootDir = new String[] { Environment.getExternalStorageDirectory()+"/test"};
? mScanConnection = MediaScannerFile.scanFile(this, rootDir, null, this);
?}
记得在退出时调用:
public void destroy() {
? if (null != mScanConnection && mScanConnection.isConnected()) {
? ?mScanConnection.disconnect();
? }
?}
系统扫描完的数据全部放置在下面目录所对应的数据库中:

分internal和external两个名词,分别是机身内部存储和外部存储。
internal中存放了系统自带的一些媒体,如:铃声、预置图片、视频等,一般是在
/system/media/目录下。
external是除internal之外的存储空间,内部sdcard、外部sdcard等;
我们导出external数据库,查看一下有哪些表,都是做啥的,如下图:

下面的例子是从audio表中查询所有音乐的详细信息:
?public CenterMusicInfo queryMusicById(long id) {
? Cursor cursor = mContext.getContentResolver().query(
? ? MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
? ? new String[] { MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DURATION, MediaStore.Audio.Media.ARTIST,
? ? ? MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.YEAR, MediaStore.Audio.Media.MIME_TYPE, MediaStore.Audio.Media.SIZE, MediaStore.Audio.Media.DATA,MediaStore.Audio