Android媒体的一些使用总结

原文:http://blog.csdn.net/kallyena/article/details/7107070

http://blog.csdn.net/lgl125/article/details/7559124

http://hi.baidu.com/zlykeepon/item/6c5db3eec1f74f2c5b2d64dd


主要分为几节:

1. Android的媒体文件内部是如何存储的?

2. Andoid的媒体文件如何获取?

3. 在使用媒体文件的一些小技巧。

 

 1.      Android的多媒体如何存储的?

Android的多媒体文件主要存储在/data/data/com.android.providers.media/databases目录下,该目录下有两个db文件,一个是内部存储数据库文件(internal.db),一个是存储卡数据库(external-XXXX.db)。媒体文件的操作主要是围绕着这两个数据库来进行。这两个数据库的结构是完全一模一样的。

我们先看一下这两个数据库包含了哪些表。

album_art            audio                search

album_info           audio_genres         searchhelpertitle

albums               audio_genres_map     thumbnails

android_metadata     audio_meta           video

artist_info          audio_playlists      videothumbnails

artists              audio_playlists_map

artists_albums_map   images

先从基本的分析:

Images表:主要存储images信息。可以看一下这个表的结构:

CREATE TABLE images (_id INTEGERPRIMARY KEY,_data TEXT,_size INTEGER,_display_name TEXT,mime_type TEXT,title

TEXT,date_added INTEGER,date_modifiedINTEGER,description TEXT,picasa_id TEXT,isprivate INTEGER,latitude DOUBL

E,longitude DOUBLE,datetakenINTEGER,orientation INTEGER,mini_thumb_magic INTEGER,bucket_id TEXT,bucket_displa

y_name TEXT);

包含了一些基本信息,其中大家一看就明白了。

Thumbnails表:这个表和images表是有直接关系的。主要存储图片的缩略图,Android为每一张保存进系统的图片文件都会自动生成一张缩略图文件。关于这一点还有一些特殊的技巧后面再讲。我们可以看一下这个表的结构:

CREATE TABLE thumbnails (_id INTEGERPRIMARY KEY,_data TEXT,image_id INTEGER,kind INTEGER,width INTEGER,height INTEGER);

每一张image对应一条thumbnail记录。

Video表:主要存储视频信息了。和images表类似。表结构如下:

CREATE TABLE video (_id INTEGERPRIMARY KEY,_data TEXT NOT NULL,_display_name TEXT,_size INTEGER,mime_typeTEXT,date_added INTEGER,date_modified INTEGER,title TEXT,durationINTEGER,artist TEXT,album TEXT,resolution TEXT,description TEXT,isprivateINTEGER,tags TEXT,category TEXT,language TEXT,mini_thumb_data TEXT,latitudeDOUBLE,longitude DOUBLE,datetaken INTEGER,mini_thumb_magic INTEGER, bucket_idTEXT, bucket_display_name TEXT, bookmark INTEGER);

Videothumbnails表:存储视频的缩略图信息。这个和thumbnails表类似。

Audio表:音频信息比视频信息和图片信息要稍微复杂一些,主要是存储了一些专辑(album)、歌手(artists)信息,而专辑和歌手信息是单独的表格存储的,audio其实是一个视图,真正的音频数据信息存储在audio_meta表格中。我们可以看一下audio视图的定义:

CREATE VIEW audio as SELECT * FROMaudio_meta LEFT OUTER JOIN artists ON audio_meta.artist_id=artists.artist_idLEFT OUTER JOIN albums ON audio_meta.album_id=albums.album_id;

Albums表:主要存储专辑信息。

Artists表:主要存储歌手信息。不多赘述。

其他的一些表格我们平时可能用的比较少,就不做描述了,有兴趣可以自行研究一下。



2.   Android的多媒体如何获取?

Android提供了媒体获取与存储的相关API,主要包含在android.provider.MediaStorepackage中。

MediaStore.Audio.AlbumColumns

Columns representing an album  

MediaStore.Audio.ArtistColumns

Columns representing an artist  

MediaStore.Audio.AudioColumns

Columns for audio file that show up in multiple tables. 

MediaStore.Audio.GenresColumns

Columns representing an audio genre  

MediaStore.Audio.PlaylistsColumns

Columns representing a playlist  

MediaStore.Files.FileColumns

Fields for master table for all media files. 

MediaStore.Images.ImageColumns

 

MediaStore.MediaColumns

Common fields for most MediaProvider tables  

MediaStore.Video.VideoColumns

 

MediaStore

The Media provider contains meta data for all available media on both internal and external storage devices. 

MediaStore.Audio

Container for all audio content. 

MediaStore.Audio.Albums

Contains artists for audio files  

MediaStore.Audio.Artists

Contains artists for audio files  

MediaStore.Audio.Artists.Albums

Sub-directory of each artist containing all albums on which a song by the artist appears. 

MediaStore.Audio.Genres

Contains all genres for audio files  

MediaStore.Audio.Genres.Members

Sub-directory of each genre containing all members. 

MediaStore.Audio.Media

 

MediaStore.Audio.Playlists

Contains playlists for audio files  

MediaStore.Audio.Playlists.Members

Sub-directory of each playlist containing all members. 

MediaStore.Files

Media provider table containing an index of all files in the media storage, including non-media files. 

MediaStore.Images

Contains meta data for all available images. 

MediaStore.Images.Media

 

MediaStore.Images.Thumbnails

This class allows developers to query and get two kinds of thumbnails: MINI_KIND: 512 x 384 thumbnail MICRO_KIND: 96 x 96 thumbnail  

MediaStore.Video

 

MediaStore.Video.Media

 

MediaStore.Video.Thumbnails

This class allows developers to query and get two kinds of thumbnails: MINI_KIND: 512 x 384 thumbnail MICRO_KIND: 96 x 96 thumbnail  

简单的观察一下,发现这些类也就是对数据库中的一些表的封装,弄懂了底层的存储结构,对于了解这些类的作用就很容易了。

Android系统中的每一种媒体文件有两种地址描述方式。

第一种模式,大家知道,在Android中,Content Provider是用来存储和获取公共数据的统一接口,Content Provider为每一类资源分配了URI地址,比如图片的地址就包括MediaStore.Images.Media.INTERNAL_CONTENT_URI和MediaStore.Images.Media.EXTERNAL_CONTENT_URI两个基础地址,其值分别是content://media/internal/images/media和content://media/external/images/media,对应内部库和外部库地址。每一张图片的地址基本上是上面的基础URL地址下加上图片的内部ID。打个比方一张存储卡上的图片ID为2,其对应的Uri地址就是content://media/external/images/media/2.知道了这个地址,基本上就可以操作这张图片的所有信息了。

另外一种描述文件地址标识就是传统的文件路径模式了,比如一张存储卡上的图片地址可能描述为:/mnt/sdcard/images/1.jpg。其实这个路径存储在images表格中的data字段中,有了这点关联,我们可以在这两种模式下进行任意切换。

前一种模式下,主要通过MediaStore.Images.Media、MediaStore.Audio.Media、MediaStore.Video.Media三个库中的query方法来查询或者获取特定条件的媒体了。

基本用法1:从一个Content Uri地址中生成Bitmap

可以采用android.provider.MediaStore.Images.Media.getBitmap(ContentResolver cr, Uri url)方法,其中ContentResolver是应用与资源之间的衔接人,它的示例通常可以通过在Activity中调用的getContentResolver()方法中获取。Uri地址就是上面描述的content://media/external/images/media/2类似地址,也就是Content Provider定义的地址形式。

基本用法2:从一个传统地址中生成Bitmap

有时候我们只知道一张图片的路径,并不知道图片的内部地址,想去获取该图片,可以采用android.graphics.BitmapFactory中的decodeXXX方法来搞定,比如decodeFile方法就是从文件路径中读取图片,原图片可以支持jpg,png,gif,bmp等各种格式。decodeByteArray就是从字节流中解码了。最后都是转换成Bitmap格式。

基本用法3:获取一张图片的缩略图

有时候我们需要显示图片的缩略图,可以采用android.provider.MediaStore.Images.Thumbnails的 getThumbnail方法。另外其实也可以采用bitmap的compress的方法对图片进行一些压缩处理。



Android系统提供了MediaScanner,MediaProvider,MediaStore等接口,并且提供了一套数据库表格,通过Content Provider的方式提供给用户。当手机开机或者有SD卡插拔等事件发生时,系统将会自动扫描SD卡和手机内存上的媒体文件,如audio,video,图片等,将相应的信息放到定义好的数据库表格中。在这个程序中,我们不需要关心如何去扫描手机中的文件,只要了解如何查询和使用这些信息就可以了。MediaStore中定义了一系列的数据表格,通过ContentResolver提供的查询接口,我们可以得到各种需要的信息。下面我们重点介绍查询SD卡上的音乐文件信息。
先来了解一下ContentResolver的查询接口:
Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder);

Uri:指明要查询的数据库名称加上表的名称,从MediaStore中我们可以找到相应信息的参数,具体请参考开发文档。
Projection: 指定查询数据库表中的哪几列,返回的游标中将包括相应的信息。Null则返回所有信息。
selection: 指定查询条件
selectionArgs:参数selection里有 ?这个符号是,这里可以以实际值代替这个问号。如果selection这个没有?的话,那么这个String数组可以为null。
SortOrder:指定查询结果的排列顺序
下面的命令将返回所有在外部存储卡上的音乐文件的信息:
Cursor cursor = query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
得到cursor后,我们可以调用Cursor的相关方法具体的音乐信息:
歌曲ID:MediaStore.Audio.Media._ID

Int id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));

歌曲的名称 :MediaStore.Audio.Media.TITL
String tilte = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));

歌曲的专辑名:MediaStore.Audio.Media.ALBUM
String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));

歌曲的歌手名: MediaStore.Audio.Media.ARTIST
String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));

歌曲文件的全路径 :MediaStore.Audio.Media.DATA

String url = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));

歌曲文件的名称:MediaStroe.Audio.Media.DISPLAY_NAME

String display_name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));

歌曲文件的发行日期:MediaStore.Audio.Media.YEAR
String year = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.YEAR));

歌曲的总播放时长 :MediaStore.Audio.Media.DURATION
Int duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));

歌曲文件的大小 :MediaStore.Audio.Media.SIZE
Int size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));



MediaStore 与Media.EXTERNAL_CONTENT_URI

MediaStore这个类是android系统提供的一个多媒体数据库,android中多媒体信息都可以从这里提取。这个MediaStore包括了多媒体数据库的所有信息,包括音频,视频和图像,android把所有的多媒体数据库接口进行了封装,所有的数据库不用自己进行创建,直接调用利用ContentResolver去掉用那些封装好的接口就可以进行数据库的操作了。今天我就介绍一些这些接口的用法。    首先,要得到一个ContentResolver实例,ContentResolver可以这样获取,利用一个Activity或者Service的Context即可。如下所示:
    ContentResolver mResolver = ctx.getContentResolver();
   上面的那个ctx的就是一个context,Activity.this就是那个Context,这个Context就相当于一个上下文环境。得到这个Context后就可以调用getContentResolver接口获取ContentResolver实例了。ContentResolver实例获得后,就可以进行各种查询,下面我就以音频数据库为例讲解增删改查的方法,视频和图像和音频非常类似。
    在讲解各种查询之前,我给大家介绍下怎么看android都提供了哪些多媒体表。在adbshell中,找到/data/data/com.android.providers.media/databases/下,然后找到SD卡的数据库文件(一般是一个.db文件),然后输入命令sqlite3加上这个数据库的名字就可以查询android的多媒体数据库了。.table命令可以列出所有多媒体数据库的表,.scheme加上表名可以查询表中的所有列名。这里可以利用SQL语句来查看你想要的数据,记得最后一定要记住每条语句后面都加上分号。下面开始讲述怎么在这些表上进行增删改查。
    查询,代码如下所示:
    Cursor cursor = resolver.query(_uri, prjs, selections, selectArgs, order);
    ContentResolver的query方法接受几个参数,参数意义如下:
   Uri:这个Uri代表要查询的数据库名称加上表的名称。这个Uri一般都直接从MediaStore里取得,例如我要取所有歌的信息,就必须利用MediaStore.Audio.Media. EXTERNAL_CONTENT_URI这个Uri。专辑信息要利用MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI这个Uri来查询,其他查询也都类似。
    Prjs:这个参数代表要从表中选择的列,用一个String数组来表示。
     Selections:相当于SQL语句中的where子句,就是代表你的查询条件。
    selectArgs:这个参数是说你的Selections里有?这个符号是,这里可以以实际值代替这个问号。如果Selections这个没有?的话,那么这个String数组可以为null。
     Order:说明查询结果按什么来排序。
    上面就是各个参数的意义,它返回的查询结果一个Cursor,这个Cursor就相当于数据库查询的中Result,用法和它差不多。
-------------------------------------------------------------------------------------------------------------------
    增加,代码如下所以:
    ContentValues values = new ContentValues();
    values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER,0);
    resolver.insert(_uri, values);
    这个insert传递的参数只有两个,一个是Uri(同查询那个Uri),另一个是ContentValues。这个ContentValuses对应于数据库的一行数据,只要用put方法把每个列的设置好之后,直接利用insert方法去插入就好了。
    更新,代码如下:
    ContentResolver resolver = ctx.getContentResolver();
    Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    ContentValues values = new ContentValues();
    values.put(MediaStore.Audio.Media.DATE_MODIFIED, sid);
    resolver.update(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,values, where, selectionArgs);
    上面update方法和查询还有增加里的参数都很类似,这里就不再重复叙述了,大家也可直接参考google的文档,那里也写的很清楚。
    删除,代码如下:
    ContentResolver resolver = ctx.getContentResolver();
    nbsp;   resolver.delete(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,where, selectionArgs);
    delete和更新的方法很类似,大家对照更新的方法看下马上就会明白。

你可能感兴趣的:(android)