Android media媒体库分析之:调用系统媒体库完成指定媒体文件扫描

之前文章中分析了Android media媒体库,详见:http://gqdy365.iteye.com/blog/2150883

这儿说一下怎么样在自己的应用程序调用系统提供的接口完成对指定媒体文件的扫描,约定:
指定的文件:就是指定路径的文件(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();
}
}


二、获取扫描完的媒体文件详细信息:
先看媒体库整体分析:http://gqdy365.iteye.com/blog/2150883

系统扫描完的数据全部放置在下面目录所对应的数据库中:

[img]http://dl2.iteye.com/upload/attachment/0104/4765/0f0cfb71-6967-31de-9cb7-e264555e4366.png[/img]

分internal和external两个名词,分别是机身内部存储和外部存储。
internal中存放了系统自带的一些媒体,如:铃声、预置图片、视频等,一般是在
/system/media/目录下。
external是除internal之外的存储空间,内部sdcard、外部sdcard等;

我们导出external数据库,查看一下有哪些表,都是做啥的,如下图:

[img]http://dl2.iteye.com/upload/attachment/0104/4777/1dcb79f4-1813-3ea0-9f62-3706ed74bdb1.png[/img]

下面的例子是从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.Media.DATE_MODIFIED}
,MediaStore.Audio.Media._ID+"=? and ("+ MediaStore.Audio.Media.MIME_TYPE+"=? or " + MediaStore.Audio.Media.MIME_TYPE+"=? or " + MediaStore.Audio.Media.MIME_TYPE+"=? or " + MediaStore.Audio.Media.MIME_TYPE
+"=? or " + MediaStore.Audio.Media.MIME_TYPE+"=? or " + MediaStore.Audio.Media.MIME_TYPE+"=? or " + MediaStore.Audio.Media.MIME_TYPE+"=? or " + MediaStore.Audio.Media.MIME_TYPE+"=?)", new String[]{String.valueOf(id),"audio/mpeg","audio/mp4",
"audio/x-wav","audio/amr","audio/amr-wb","application/ogg","audio/aac","audio/x-ms-wma"},MediaStore.Audio.Media.DATE_MODIFIED+" desc");

CenterMusicInfo retMI = null;
try{

if (cursor.moveToFirst()) {
retMI = new CenterMusicInfo();
retMI.setId(cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID)));
retMI.setFileName(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME)));//文件名
retMI.setTitle(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)));//歌曲名
retMI.setDuration(cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)));//时长
retMI.setSinger(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)));//歌手名
retMI.setAlbum(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM)));//专辑名
retMI.setYear(cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.YEAR)));//年代
retMI.setMimeType(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.MIME_TYPE)));
retMI.setFileSize(cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE)));
retMI.setFilePath(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)));
retMI.setDateModified(cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DATE_MODIFIED)));
}
}finally{
if(cursor != null){
cursor.close();
}
}
return retMI;

}



public ArrayList<CenterMusicInfo> queryMusicList(int position,int limit) {
Uri.Builder builder = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI.buildUpon();
builder.appendQueryParameter("limit", String.valueOf(limit));
Uri uri = builder.build();
Cursor cursor = mContext.getContentResolver().query(
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.Media.DATE_MODIFIED}
, MediaStore.Audio.Media.MIME_TYPE+"=? or " + MediaStore.Audio.Media.MIME_TYPE+"=? or " + MediaStore.Audio.Media.MIME_TYPE+"=? or " + MediaStore.Audio.Media.MIME_TYPE
+"=? or " + MediaStore.Audio.Media.MIME_TYPE+"=? or " + MediaStore.Audio.Media.MIME_TYPE+"=? or " + MediaStore.Audio.Media.MIME_TYPE+"=? or " + MediaStore.Audio.Media.MIME_TYPE+"=?", new String[]{"audio/mpeg","audio/mp4",
"audio/x-wav","audio/amr","audio/amr-wb","application/ogg","audio/aac","audio/x-ms-wma"},MediaStore.Audio.Media.DATE_MODIFIED+" desc");

ArrayList<CenterMusicInfo> musicList = new ArrayList<CenterMusicInfo>();
try{

if (cursor.moveToPosition(position)) {
do {
CenterMusicInfo musicInfo = new CenterMusicInfo();
musicInfo.setId(cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID)));
musicInfo.setFileName(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME)));//文件名
musicInfo.setTitle(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)));//歌曲名
musicInfo.setDuration(cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)));//时长
musicInfo.setSinger(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)));//歌手名
musicInfo.setAlbum(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM)));//专辑名
musicInfo.setYear(cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.YEAR)));//年代
musicInfo.setMimeType(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.MIME_TYPE)));
musicInfo.setFileSize(cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE)));
musicInfo.setFilePath(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)));
musicInfo.setDateModified(cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DATE_MODIFIED)));
musicList.add(musicInfo);
}while(cursor.moveToNext());
}
}finally{
if(cursor != null){
cursor.close();
}
}

return musicList;

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章