`

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

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



分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.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;

	}
  • 大小: 16.7 KB
  • 大小: 16.7 KB
  • 大小: 5.2 KB
分享到:
评论

相关推荐

    android多媒体框架

    JAVA程序通过JNI接口实现对底层媒体库libmedia.so的调用; MediaPlayer在运行的时候,可以大致上分成Client和Server两个部分,它们分别在两个进程中运行,它们之间使用Binder机制实现IPC通讯,图中...

    基于Android扫描sd卡与系统文件的介绍

    当手机或模拟器开机时,会调用android的MediaScanner,扫描sd卡和内存里的文件。以下是log信息。 代码如下:12-13 15:39:11.062: VERBOSE/MediaPlayerService(67): Create new media retriever from pid 349&lt;BR&gt; 12-...

    深入理解Android:卷I--详细书签版

    10.2.3 android.process.media媒体扫描工作的流程总结 471 10.3 MediaScanner分析 472 10.3.1 Java层分析 472 10.3.2 JNI层分析 476 10.3.3 PVMediaScanner分析 479 10.3.4 关于MediaScanner的总结 485 10.4 ...

    Android多媒体框架

    Android 系统架构从下到上依次是 Linux 内 核,本地库,应用框架层和应用层,我们可以看到 MediaFramework 处于本地库 Libraries 这一层,该层不是用 java 实现的,一般是 C/C++,它们通过 java 的 JNI 方 式调用。

    VC调用windows media player插件

    讲解了VC6.0调用windows media player 插件,播放本地的多种视频文件(需要自己安装解码库)。包含了一个调用插件的实例,编程中碰到的疑问解答,调用插件的详细步骤文档。程序有打开文件、播放、暂停、全屏、显示...

    IPlayer:Android的媒体播放器库

    播放器快速开发框架(播放库)背景:在日常项目中,经常会有多媒体相关音、视频模块开发需求,介于Android系统默认多媒体播放整体使用流程比较复杂,在此分享一下这个小型的多媒体应用快速开发框架。框架封装了...

    新版Android开发教程.rar

    ----------------------------------- Android 编程基础 1 封面----------------------------------- Android 编程基础 2 开放手机联盟 --Open --Open --Open --Open Handset Handset Handset Handset Alliance ...

    Android 代码分析

    1 Android build system 4 1.1 Basic 4 1.2 Executable 6 1.3 Shared Library 9 2 Android Initialization Process 11 3 Android JAVA AIDL Analysis 15 4 Android JAVA Binder IPC System 20 5 Android Media ...

    多媒体播放器 VLC Media Player 3.0.14 + x64 中文多语免费版.zip

    在 Windows,Linux 以及某些平台,VLC 提供了一个 Mozilla 扩充包,使得某些网站上附带的QuickTime及Windows Media多媒体文件,可以在非微软或苹果计算机的操作系统中,正常显示于Mozilla 的浏览器下。 从版本 0.8.2...

    Android底层开发技术实战详解--内核、移植和驱动.(电子工业.王振丽).part3

    全书分为19章,依次讲解驱动移植的必要性,何为hal层深入分析,goldfish、msm、map内核和驱动解析,显示系统、输入系统、振动器系统、音频系统、视频输出系统的驱动,openmax多媒体、多媒体插件框架,传感器、照相机...

    nova-media-library:Laravel Nova字段,用于显示和更新Spatie媒体库模型

    Laravel Nova媒体库注意:请考虑改用,它对各种媒体库功能提供了更多支持,可能会更好地满足您的需求!该软件包旨在与。使用此程序包,您可以添加用于将单个文件上传到资源的图像字段,用于其他类型的通用文件字段,...

    Android底层开发技术实战详解--内核、移植和驱动.(电子工业.王振丽).part1

    全书分为19章,依次讲解驱动移植的必要性,何为hal层深入分析,goldfish、msm、map内核和驱动解析,显示系统、输入系统、振动器系统、音频系统、视频输出系统的驱动,openmax多媒体、多媒体插件框架,传感器、照相机...

    Android底层开发技术实战详解--内核、移植和驱动.(电子工业.王振丽).part2

    全书分为19章,依次讲解驱动移植的必要性,何为hal层深入分析,goldfish、msm、map内核和驱动解析,显示系统、输入系统、振动器系统、音频系统、视频输出系统的驱动,openmax多媒体、多媒体插件框架,传感器、照相机...

    Android获取相册图片-实现选择相册图片功能

    这就需要借助媒体库的内容提供者MediaProvider,通过它,我们不仅可以读取图片,还可以读取视频,音频。 下面我们来看一下媒体库的内容提供者的URI(源码地址) 媒体库Uri 图片MediaStore.Images.Media.EXTERNAL_...

    asset-manager-framework:使用外部资产提供商(例如DAM)覆盖WordPress媒体库的框架

    该WordPress插件提供了一个框架,用于用来自外部提供商(例如DAM,另一个WordPress网站或多站点安装中的中央站点)的资产替换标准WordPress媒体库的内容。 它处理与WordPress(Ajax端点和Backbone组件)的必要集成...

    使用Python创建快速创建剪映草稿轨道,自动生成视频

    1. 添加一个媒体到轨道顺序 `草稿媒体库` -&gt; `内容媒体库`-&gt; `轨道片段` 2. `add_media_to_track` 会识别媒体类型,加入到对应轨道。 3. 当没有视频轨道时,创建音频轨道会先创建视频轨道。 if __name__ == "__main_...

    bucklescript-serverless-media-pipeline-demo:使用无脚本脚本和无服务器的媒体处理管道概念验证

    媒体管道演示这是一个示例项目,演示了如何使用BuckleScript和无服务器使用AWS API Gateway和Lambda构建媒体处理管道。 它与的。正在安装首先,您需要安装opam软件包管理器:。 然后,您需要在安装Node.js和npm :。...

    vc++ 应用源码包_1

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

    vc++ 应用源码包_2

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

    vc++ 应用源码包_3

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

Global site tag (gtag.js) - Google Analytics