Android 多媒体【转】
第11章 Android多媒体
通过调用Android的API,可以实现相册,播放器,录音和摄像等功能。这一章需要掌握如下功能:
q 多媒体的ContentProvider的调用
q Camera
q AudioRecord和AudioTrack
q MediaPlayer
11.1 获取多媒体信息
多媒体信息?在pc中的音乐播放器总是很容易的显示歌手名、歌曲名、专辑名、年代。在Android中应该如何获取这些信息呢?
<?XML:NAMESPACE PREFIX = ST1 ?> 11.1.1 查看多媒体ContentProvider
前面我们学习了ContentProvider来保存和检索数据,Android为常用的数据类型(如:音视频、图片和联系方式等)提供了大量的ContentProvider,它们被定义在android.provider包下。那么我们如何获取多媒体的ContentProvider呢。
(1) 在Eclipse中添加Android自带的FileExplorer视图:
菜单栏->window->show view->other->Android->FileExplorer
(2) 开启模拟器,在FileExplorer中查看data/data/com.android.providers.media/databases/(如图11.1)
(3) 将external.db文件 pull到pc上,用sqlite工具(可以使用火狐插件SQliteManager)查看:(如图11.2)
(4) 查看表结构:
audio_meta:管理sd卡中的音频资源。(如图11.3)
video:管理sd卡中的视频资源。(如图11.4)
images:管理sd卡中的图片。(如图11.5)
图11.1 多媒体数据库所在包
图11.2 多媒体数据库表
图11.3 音频表结构(audio_meta)
图11.4 视频表结构(video)
图11.5 图片表结构(images)
可能大家看到这里会不明白为什么讲多媒体先要介绍这些。笔者这里给大家列举一个音乐播放器的需求:
1) 获得音乐文件列表及路径
2) 获得音乐文件属性(歌曲名、歌手名、专辑、年代。。)
3) 手动删除内存卡中音乐文件,如何能同步更新文件列表
如果是没有Android经验,大家可能会这样分析:
文件路径嘛,我调用file.listFile()就可以得到音乐文件列表。如果内存卡里有很多文件,那么这个将会特别的耗时,如果让用户等上10秒去扫描存储卡,用户很有可能将你的应用卸载掉。
音乐文件属性一般保存在音乐文件中,有的放在文件头,有的放在文件尾,必须读出该文件相关字节中的内容才可以获取音乐文件信息。OK,有个开源的项目,可以解析MP3文件中的文件信息。但是它同样也是耗时的操作。而且学会调用这个开源项目还需要一周的时间。做一个项目没那么难吧?
在文件管理器中手动删除或添加一个音乐文件,这个时候如何把它更新到音乐列表中呢,当你选择一首歌播放的时候,很有可能已经被删掉了。总不能让它时刻去调用file.listFile()去维护吧?
那么我们到底应该怎么做呢?你要始终相信Android是强大的,它早已为我们提供了这些功能,我们只需要调用Android提供的API,就可以解决上述的需求。
现在我们先看个图,图11.6为模拟器开机时,在log中打印的日志。
图11.6 开机时的log
大家会看到,系统会调用MediaScanner去扫描Internal和External Volume。原来,在开机时,系统会在后台扫描内存和外存设备,将多媒体数据更新到数据库中。同时也会扫描文件信息,这样,我们不费吹灰之力就解决了问题。
小插曲:之前由于笔者还不知道这个方法,在摸索中让同事去研究解析MP3文件信息,花了他一个星期时间,当他做出来了,我花了十分钟找到了这个方法。真是罪过罪过。
那么我们如何得到多媒体数据呢,请看下面的例子:
/**
* 读取sd卡中的音乐文件
* @return
* @throws Exception
*/
public static ArrayList<Song> readDataFromSD(Context context,int component){
// Log.i(TAG, "scanFile");
Cursor cursor = context.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.MIME_TYPE+"=? or " + MediaStore.Audio.Media.MIME_TYPE+"=?", new String[]{"audio/mpeg","audio/x-ms-wma"},null);
ArrayList<Song> songs = null;
if (cursor.moveToFirst()) {
songs = SongInfoUtil.getList(cursor, context, component);
}
return songs;
}
/**
* @author stayzhang 封装信息至Song
*/
public class SongInfoUtil {
// private static final String TAG = "ListUtils";
public static ArrayList<Song> getList(Cursor cursor, Context mContext, int component) {
Song song = null;
do {
// Log.i(TAG, "getList");
song = new Song();
song.setFilename(cursor.getString(1));//文件名
song.setTitle(cursor.getString(2));//歌曲名
song.setDuration(cursor.getInt(3));//时长
song.setSinger(cursor.getString(4));//歌手名
song.setAlbum(cursor.getString(5));//专辑名
if (cursor.getString(6) != null) {//年代
song.setYear(cursor.getString(6));
} else {
song.setYear("未知");
}
if ("audio/mpeg".equals(cursor.getString(7).trim())) {//歌曲格式
song.setType("mp3");
} else if ("audio/x-ms-wma".equals(cursor.getString(7).trim())) {
song.setType("wma");
}
if (cursor.getString(8) != null) {//文件大小
float temp = cursor.getInt(8) / 1024f / 1024f;
String sizeStr = (temp + "").substring(0, 4);
song.setSize(sizeStr + "M");
} else {
song.setSize("未知");
}
if (cursor.getString(9) != null) {//文件路径
song.setFileUrl(cursor.getString(9));
}
} while (cursor.moveToNext());
cursor.close();
return dbService.query(component, null, null);
}
}
同理,图片还有视频文件也可以这样获得,不再赘述。
这样第一个和第二个需求我们已经解决,那第三个需求呢。
当我们手动的删除或添加多媒体文件到存储卡中时,Android会自动扫描这些文件并将其更新到数据库吗?
答案是不会,那么我们如何将数据实时更新到数据库中呢。还记得logcat中打印出来的MediaScanner吗?我们也可以调用MediaScanner这个类去扫描存储卡。但是不能直接调用这个类,只能以广播的形式通知系统,让系统去扫描存储卡指定的URI,扫描完后,再通过ContentProvider查询数据库。
方法如下:
/**
* 调用系统api扫描sd卡
*/
private void scanSdCard() {
IntentFilter intentFilter = new IntentFilter(
Intent.ACTION_MEDIA_SCANNER_STARTED);
intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
intentFilter.addDataScheme("file");
scanReceiver = new ScanSdFilesReceiver();
registerReceiver(scanReceiver, intentFilter);
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + getExternalStorageDirectory().getAbsolutePath)));
}
/**
* @author stayzhang 注册扫描开始/完成的广播
*/
private class ScanSdFilesReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_MEDIA_SCANNER_STARTED.equals(action)) {
//当系统开始扫描sd卡时,为了用户体验,可以加上一个等待框
scanHandler.sendEmptyMessage(STARTED);
}
if (Intent.ACTION_MEDIA_SCANNER_FINISHED.equals(action)) {
//当系统扫描完毕时,停止显示等待框,并重新查询ContentProvider
scanHandler.sendEmptyMessage(FINISHED);
}
}
}
OK,关于多媒体的ContentProvider的知识告一段落,下面就是如何调用Android API来使用这些多媒体文件。
11.1.2 使用Camera
11.2 使用视频
11.2.1 录制视频
11.2.2 播放视频
11.3 使用音频
11.3.1 录制音频
11.3.2 播放音频
11.3.3 共享音频
11.3.4 使用音频
转载于:https://www.cnblogs.com/zhwl/archive/2011/08/10/2133809.html
Android 多媒体【转】相关推荐
- Android 多媒体综述
Android 多媒体综述 多媒体系统是Android中最为庞大的系统,涉及了硬件抽象层.编解码.OpenCore多媒体框架.Android多媒体框架.Java层接口多方面的内容. 一.引言 本系列内 ...
- Android多媒体之GLES2战记第四集--移形换影
视野限制了人对这个宇宙的认知,但没有视野,人将会一无所知 上集说到勇者坠入黑暗之渊,凭借对世界的认知构建出了世界系 到此为止,OpenGL的世界观已经映入脑海,新手十二副本已经通过 接下来等待他们的将 ...
- Android多媒体开发
Android多媒体开发系列文章 Android多媒体开发:录音机 Android多媒体开发:照相机 TextureView+MediaPlayer实现在线短视频播放 Android多媒体开发:第三方 ...
- Android 多媒体视频播放一( 多媒体理解与经验分享)
前言 说到android的多媒体,一把辛酸一把泪,当初听说会多媒体的比较牛掰,公司也有需求,于是乎我也积极的加入研究android多媒体的行列,记得以前刚接触的时候,最开始还是比较头大的,主要是但是很 ...
- Android多媒体整体架构图
Android多媒体整体架构图 MediaPlayer框架图 Camera框架图 SoundRecorder框架图 VideoCamera框架图 OpenCore与Skia ALSA Audio框架图 ...
- Android多媒体开发(3)————使用Android NKD编译havlenapetr-FFMpeg-7c27aa2
1. 使用NDK去编译官方的FFmpeg原版的话,还得自己实现JNI层与Java层,工程量比较大.所以移植FFmpeg到Android平台时,可以移植一些已经实现JNI与JAVA层的开源项目,毕竟软件 ...
- android多媒体框架学习 详解
原址 一:多媒体框架概述 jellybean 的多媒体跟以前的版本,通过对比没啥变化,最大的变化是google终于舍得给multimedia建个独立的git了(framework/av),等你好久了! ...
- android车载系统测试,一种车载Android多媒体主机的自动测试方法和系统与流程
本发明涉及车载多媒体主机的测试方法和装置领域,特别是涉及一种车载Android多媒体主机的自动测试方法和系统. 背景技术: 目前在车载多媒体主机的研发过程中,对车载多媒体主机进行压力测试是不可缺省的一 ...
- android多媒体框架学习 详解 最新版本
一:多媒体框架概述 jellybean 的多媒体跟以前的版本,通过对比没啥变化,最大的变化是google终于舍得给multimedia建个独立的git了(framework/av),等你好久了!也体现 ...
最新文章
- opengl版本发展史及各种概念的厘清
- pthread_cleanup_push
- HDU_2065 红色病毒问题(指数型生成函数)
- 顺序表的应用——逆置问题
- Silverlight学习(一) 创建Silverlight项目,构建一个简单的Silverlight Demo
- 【Matlab】方差是偏离均值的程度,那偏离中位数的程度怎么算呢?
- 网站如何快速搭建即时响应客服系统
- magenta内核与linux,谷歌将推出新操作系统Fuchsia:Magenta语言为内核
- Docker安装ActiveMQ(docker-compose.yml)
- Mybatis的几种传参方式
- spring boot guava cache 缓存学习
- 耶鲁大学公开课:哲学-死亡
- 升级到jdk1.8后 sun/io/CharToByteConverter错误及处理
- java读取、写入保存、遍历ini文件配置数据
- Python处理Excel数据的方法
- 1.9 LaTex边注与脚注
- 怎么禁用计算机usb驱动程序,win7如何禁止USB自动安装驱动程序
- 零基础学C语言之初识C语言(上)
- Brain:一种用于阿尔兹海默症(AD)分类的可解释的深度学习框架
- 生鲜配送管理系统_升鲜宝 V2.0 小程序辅助系统工具矩阵系列相关说明
热门文章
- CodeSmith 创建Ado.Net自定义模版(一)
- Enterprise Library:DAAB + OLEDB/ODBC操作Access数据库
- python进阶教程之异常处理
- windows xp下安装java8(jdk8)-转
- [Java] 蓝桥杯ALGO-58 算法训练 字串逆序
- L2-024. 部落-PAT团体程序设计天梯赛GPLT
- L2-026 小字辈-PAT团体程序设计天梯赛GPLT
- Nexus启动失败处理:The nexus service was launched, but failed to start.
- 君信财富获数千万元战略投资,投资方为银江集团
- python之路---15 装饰器