`

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扫描音乐文件

    这个过程涉及到文件系统操作、媒体库访问以及UI显示等多个技术环节。以下是对这些知识点的详细说明: 1. **文件系统操作**:Android设备的文件系统通常采用Linux内核,因此遵循POSIX标准。音乐文件通常存储在外部...

    androidx.media3.exoplayer,编译好的libvp9(libvpx)库

    6. **多媒体扩展**:AndroidX.media3库可能还包含了其他媒体相关的组件,可以方便地扩展到其他格式或特性,如AAC音频解码、HDR视频支持等。 7. **动态 Adaptive Streaming**:ExoPlayer支持DASH(Dynamic Adaptive ...

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

    `MediaScannerService`的`scanFile`方法接收文件路径和MIME类型作为参数,然后对指定文件进行扫描,并返回一个Uri,表示扫描后在媒体库中的位置。 在扫描过程中,`MediaScanner`会解析多媒体文件的元数据,如文件名...

    Android 拍照更新媒体库,相册选取图片显示

    在Android平台上,拍照并更新媒体库以便用户能在相册中查看新拍摄的图片是一个常见的功能。这个过程涉及多个步骤,包括请求相机权限、启动相机应用、处理返回的图像数据、保存图片到设备以及通知媒体库更新。下面...

    Android媒体库框架(mediascanner).doc

    Android 媒体库框架(MediaScanner)是 Android 平台上的一种媒体文件管理机制,旨在提供一个统一的媒体文件管理方式,帮助用户快速地浏览和管理媒体文件。 媒体文件管理机制 在桌面系统上,媒体文件通常呈树状...

    android-media-picker,一个简单易用的媒体选择器android库。从设备中选择任何图像、视频或音频.zip

    1. **设计目的**:Android Media Picker的目标是为开发者提供一个轻量级、高度可定制的媒体选择解决方案,使用户可以快速浏览和选择设备上的多媒体文件,无需编写大量的自定义代码。 2. **功能特性**:该库支持多选...

    android的多媒体系统.pdf

    - **本地调用部分 (JNI)**: 位于`frameworks/base/media/*`目录,最终被编译成`libmedia_jni.so`库。 **2.3 基于OpenCore的多媒体播放器和记录器** - **外部OpenCore项目**: 包含多种编解码器和多媒体处理组件,...

    android多媒体框架详细分析

    1. **数据源信息获取**: 通过调用`setDataSource()`方法指定文件路径或网络URL。 2. **数据源解析**: PVPlayer层解析数据源信息,准备加载数据。 3. **数据通道建立**: 建立从数据源到PVPlayer的数据通道。 ##### ...

    Android多媒体框架分析.pdf

    Android 多媒体框架分析 Android 多媒体框架是 Android 系统中负责处理多媒体任务的核心组件,包括音频、视频、图像等多媒体数据的处理和播放。基于 PacketVideo 公司的 OpenCORE 平台,多媒体框架提供了一套通用的...

    Android多媒体扫描过程.pdf

    - 扫描完成后,这些信息会被更新到系统的媒体库,供用户通过音乐、视频或图片应用访问。 8. **性能优化**: - 由于解析媒体文件可能耗时较长,所以这个过程通常在后台运行,避免影响用户体验。 - 对于不支持的...

    Android 媒体库数据更新方法总结

    当扫描完成时,`onScanCompleted`回调会被调用,提供扫描的文件路径和生成的URI,表明文件已成功加入媒体库。 总之,当在Android应用中处理外部存储的媒体文件时,确保及时更新媒体库至关重要。通过使用`...

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

    扫描完成后,系统会更新媒体库,使得用户可以在音乐、视频或图片应用中看到新扫描到的媒体文件。 9. **性能优化**: 为了提高性能,扫描过程可能涉及缓存技术,以减少对数据库的直接访问。同时,通过JNI(Java ...

    android usb扫描音视频,并播放

    你可以通过`MediaScannerConnection`类来调用此服务,将新插入的USB设备中的媒体文件添加到系统的媒体库中。 3. **多媒体框架(MediaPlayer)**:`MediaPlayer`类是Android用于播放音频和视频的核心组件。它可以...

    Pro Android学习:media frameworks小例子

    5. **使用MediaStore**:可能的例子是将录制的媒体文件插入到MediaStore,以便用户可以通过系统的媒体库访问,或者通过ContentResolver查询录制文件的信息。 在`TestMedia`这个文件中,可能包含了实现以上操作的...

    Qt for Android 调用原生系统摄像头进行录像并保存输出

    在Android平台上开发应用程序时,Qt框架提供了一个强大的跨平台解决方案,允许开发者使用相同的代码库在多个操作系统上运行。本文将详细介绍如何使用Qt for Android调用原生系统的摄像头进行录像,并保存录制的视频...

    Android多媒体框架初步分析

    它可以播放资源文件、独立文件系统中的文件,甚至是通过数据连接的流媒体。`android.media.MediaPlayer`类提供了完整的音频和视频播放能力。 - **MediaRecorder**:用于录制音频。未来的版本可能会支持视频录制功能...

    VLC播放流媒体arr文件

    在Android平台上使用VLC进行流媒体播放时,有时会涉及到特定的配置文件,例如“arr”文件。这个文件对于理解VLC在Android上的流媒体处理机制至关重要。 "arr"文件全称为"Advanced Playlist Representation",它是...

    android media source

    在Android系统中,媒体源(Media Source)是一个关键的概念,它是多媒体播放的基础。Media Source代表了一个可以提供连续媒体数据的源头,例如音频、视频或它们的组合。Android平台提供了多种方式来创建和处理媒体源...

    Android流媒体的播放

    2. **Android Media Player API**:Android系统内置了Media Player类,它是实现流媒体播放的核心。通过这个API,开发者可以轻松地集成RTSP流媒体播放功能。Media Player支持多种流媒体协议,包括RTSP,使得在Android...

Global site tag (gtag.js) - Google Analytics