前两篇文章通过麦克风硬件和摄像头硬件分别采集音频和视频的多媒体数据,在得到的多媒体数据通常是以编码文件的格式存储,在用户需要展示时,可通过设备的内置扩音器或蓝牙耳机等硬件播放音频,通过设备的显示屏或外接投影仪等硬件播放照片、动画或视频。
可以将这些展示类设备分为两类。
一类是内置类多媒体硬件,是通过线路硬连接到设备CPU控制中心,所以在应用程序中可直接调取系统提供的相关接口直接使用这类设备。比如移动手机的内置扩音器、听筒、有线耳机、屏幕等硬件。
另一类是外接类多媒体硬件,是通过配合下文即将介绍的蓝牙或网络等通讯类硬件,通过无线软连接到设备CPU控制中心,在使用这类设备前,必须先配合通讯类硬件的使用。比如蓝牙耳机、投影仪等硬件。
本篇只介绍在内置类多媒体硬件上的使用流程。
对于音频的播放,主要借助内置扩音器,使用系统提供的android.media.MediaPlayer类。
使用其无参构造方法后,调用该对象的setDataSource(String path)
等系列方法,设置要播放的音频源。该系列方法有多个重写,除了上边参数 path 所表示的本地文件格式的音频源,还可以设置远程网络 Uri 格式的音频源。
除此之外,还需要设置播放的音频流类型,不过设置方法在不同版本上有所区别。
在Android5.0即API级别21之前,调用setAudioStreamType(int streamtype)
方法,参数 streamtype 是由android.media.AudioManager音频管理类定义的常量,其值包括标记为语音通话音频流的AudioManager.STREAM_VOICE_CALL=0
,标记为系统音频流的AudioManager.STREAM_SYSTEM=1
,语音铃声的AudioManager.STREAM_RING=2
,或者多媒体音乐流的AudioManager.STREAM_MUSIC=3
等多种音频流类型。
从Android5.0即API级别21开始,改用setAudioAttributes(AudioAttributes attributes)
方法,参数 attributes 是android.media.AudioAttributes音频属性类构造的对象,而AudioAttributes
对象则是通过android.media.AudioAttributes.Builder建造者模式构造的。在无参构造建造者AudioAttributes.Builder
对象后,调用setUsage(int usage)
方法设置音频属性的使用者,调用setContentType(int contentType)
方法设置音频流内容类型,上述方法中的参数 usage 和参数 contentType 都是AudioAttributes
定义的常量值。之后通过build()
方法返回AudioAttributes
音频属性类的实例化对象。
在音频相关参数设置之后,就可以准备音频以通过系统获取相关硬件设备了。
在加载本地的小文件时,可以直接调用 prepare()
方法,代码执行到此处时会停止后续代码运行,直到获取到相关资源,才会继续执行音频准备完成之后的相关操作。因此在系统主线程中调用该方法时需要注意ANR异常。
通常在加载网络资源或过大的文件时,调用prepareAsync()
方法,该方法会异步获取相关资源,后续代码继续执行,而当应用程序获取到相关资源后,将回调setOnPreparedListener(MediaPlayer.OnPreparedListener listener)
中传入的 listener 参数对象的onPrepared(MediaPlayer mp)
方法,而这里的参数 mp 也就是上文调用prepareAsync()
的MediaPlayer
对象。因此在实现android.media.MediaPlayer.OnPreparedListener接口的onPrepared(MediaPlayer mp)
方法中,可以继续执行音频准备完成之后的相关操作。
在音频准备完成之后,便可以在合适的时机执行音频的播放流程了。
调用start()
方法即可开始播放;
在音频播放过程中,同样可以调用pause()
方法暂停播放;
调用seekTo(long msec, int mode)
方法可以将播放位置移动到参数 msec 指定的毫秒级同步时刻,参数 mode 是MediaPlayer
中的常量值,包括实际定位到参数 msec 指定的同步位置之前的MediaPlayer.SEEK_PREVIOUS_SYNC=0
,实际定位到参数 msec 指定的同步位置之后的MediaPlayer.SEEK_NEXT_SYNC=1
,实际定位到参数 msec 指定的同步位置最近的MediaPlayer.SEEK_CLOSEST_SYNC=2
等几种可选模式;
调用stop()
方法停止播放,将会释放应用程序所获取的包括硬件的相关资源。
对于静态图片的展示,通常使用android.widget.ImageView类似控件,直接加载静态图片。
对于无声的动态图展示,通常使用android.view.SurfaceView控件,在该控件上可以绘制几乎任何你能想到的效果。
对于自带音频的有声动图(即视频)展示,可以使用上述方案的结合,也可使用系统提供的android.widget.VideoView控件,可以更方便的加载视频并展示。
同时,由于图片或视频展示都只是借助屏幕绘制,所以使用界面绘制展示一文中的相关知识内容即可实现。而且其他开发者和团队也开发了一系列的相关库以供使用,这在学习过程中并不算难点,故不再赘述。