【Android】多媒体

本章介绍App开发常见的多媒体技术,主要包括如何使用各种图像控件实现自定义相册、如何使用几种主要的音频播放技术、如何使用几种常见的视频播放控件、如何在屏幕上划分多窗口进行特殊处理。

相册

本节介绍自定义相册的实现过程,首先说明使用画廊或循环视图如何实现简单的相册,接着阐述使用图像切换器如何实现相册的左右滑动功能,然后分别介绍卡片视图与调色板的用法,并结合上述图像控件完成一个图片查看器------青青相册。

画廊Gallery

前几章使用文件对话框打开图片时只能看到图片的文件名,看不到图片的缩略图,对用户来说很不方便,因为光看文件名怎么知道这张图片什么模样呢?如果是在电脑上,就可以查看一组图片的缩略图列表,很容易找到想要的图片。在手机上可以使用相应的图像控件做出缩略图展示的相册效果。

画廊Gallery是专门用于展示图片列表的控件,左右滑动手势即可展示内嵌的图片列表,画面效果类似于一个平面万花筒。尽管Android将Gallery标记为Deprecation(表示已废弃),建议开发者采用HorizontalScrollView或ViewPager代替,不过Gallery用来轮播图片是一个挺好的选择。不妨了解一下Gallery控件,并结合其他控件加深对图像开发的理解。

下面是Gallery的常用方法说明。

  • setSpacing:设置图片之间的间隔大小,对应的XML属性是spacing。
  • setUnselectedAlpha:设置未选定图片的透明度,对应的XML属性是unselectedAlpha。取值范围为0.0~1.0,0.0表示完全透明,1.0表示完全不透明。
  • setAdapter:设置画廊的适配器。
  • getSelectedItemId:获取当前选中的视图序号。
  • setSelection:设置当前选中第几个视图。
  • setOnItemClickListener:设置单项的点击监听器。
    使用画廊看起来很简单,接下来试着用Gallery结合ImageView实现观看画廊的相册效果。首先在布局文件中放置一个框架布局FrameLayout,里面放一个画廊控件与一个图像视图控件,ImageView设置为充满整个屏幕,Gallery放在屏幕下方;然后监听Gallery控件的单项点击事件,当用户点击指定图片项时,使用ImageView控件填充该图片,也就是点小图看大图。
图像切换器ImageSwitcher

读者可能已经发现,前面Gallery相册在切换大图时比较生硬,前后两张图片闪一下就切过去了,用户体验不够友好。有没有办法让图片切换自然一些呢,比如通过渐变动画的方式?答案肯定是有的,就是把占据整个屏幕的图像视图ImageView换成图像切换器ImageSwitcher,然后通过ImageSwitcher实现前后图片的切换动画。

ImageSwitcher继承自视图动画器ViewAnimator,用于承载前后两个图像的变换动画。

下面介绍ImageSwitcher的常用方法。

  • setFactory:设置一个视图工厂。该视图工厂由ViewFactory派生而来,需重写makeView方法返回工厂的具体视图。对于ImageSwitcher来说,工厂返回的是ImageView对象。
  • setImageResource:设置当前图像的资源ID。该方法与下面的setImageDrawable方法和setImageURI方法为三选一操作,调用了其中一个方法,就无须调用另外两个方法。
  • setImageDrawable:设置当前图像的Drawable对象。
  • setImageURI:设置当前图像的URI地址。
  • setInAnimation:设置后一个图像的进入动画。
  • setOutAnimation:设置前一个图像的退出动画。
音频播放

本节介绍了音频播放的几种方式,首先说明了铃声工具的适用场合与简单用法,接着阐述了声音池的运用场景,它的优缺点,以及基本用法,然后说明了音轨的产生背景,以及如何进行音轨的录制和播放。

铃声Ringtone

在第9章的时候,提到媒体播放器MediaPlayer既可用来播放视频,也可用来播放音频。可在具体的使用场合,MediaPlayer不可避免地存在某些播音方面的不足之处,主要包括:

(1)MediaPlayer的初始化比较消耗资源,尤其是播放短小铃音时反应偏慢。

(2)一个MediaPlayer同时只能播放一个媒体文件,无法同时播放多个声音。

(3)MediaPlayer只能播放已经完成编码的音频文件,无法直接播放原始音频,也不能流式播放(即边录边播)。

以上问题各有不同的解决方案,对第一个问题来说,Android提供了铃声工具Ringtone处理铃音的播放。而铃声对象则是通过铃声管理器RingtoneManager的getRingtone方法来获取,具体而言,铃声管理器允许获得三种来源的铃声,说明如下:

(1)系统自带的铃音,其Uri的获取方式举例如下:

RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE); // 来电铃音

铃声管理器支持的系统铃音类型取值说明见表13-2。

(2)内部存储与SD卡上的铃音文件,其Uri的获取方式举例如下:

Uri.parse("file:///system/media/audio/ui/camera_click.ogg"); // 相机快门声

(3)App工程中res/raw目录下的铃音文件,其Uri的获取方式举例如下:

Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.ring); // 从资源文件中获取铃音

通过铃声管理器获得铃声对象之后,才能进行铃声的播放操作。下面是Ringtone的常用方法说明:

play:开始播放铃声。

stop:停止播放铃声。

isPlaying:判断铃声是否正在播放。

声音池SoundPool

对于MediaPlayer无法同时播放多个声音的问题,Android提供了声音池工具SoundPool,使用声音池即可对多个声音的播放进行调度。

使用SoundPool可以事先加载多个音频,在需要时再播放指定音频,这样有几个好处:

(1)资源占用量小,不像MediaPlayer那么耗资源。

(2)相对MediaPlayer来说,延迟时间非常小。

(3)可以同时播放多个音频,从而实现游戏过程中多个声音叠加的情景。

当然,SoundPool带来方便的同时也做了一部分牺牲,下面是它的一些使用限制:

(1)SoundPool最大只能申请1MB的内存,这意味着它只能播放一些很短的声音片段,不能用于播放歌曲或者游戏背景音乐。

(2)虽然SoundPool提供了pause和stop方法,但是轻易不要使用这两个方法,因为它们可能会让App异常或崩溃。

(3)SoundPool建议播放ogg格式的音频,据说它对Wav格式的支持不太好。

(4)待播放的音频要提前加载进声音池,不要等到要播放的时候才加载,否则可能播放没声音。因为SoundPool不会等音频加载完了才播放,而MediaPlayer会等待加载完毕才播放。

下面是SoundPool的常用方法说明。

  • 构造函数:可设置最大音频个数、音频类型、音频质量。其中音频类型一般是AudioManager.STREAM_MUSIC,音频质量取值为0到100。
  • load:加载指定的音频文件。返回值为该音频的编号。
  • unload:卸载指定编号的音频。
  • play:播放指定编号的音频。可同时设置左右声道的音量(取值为0.0到1.0)、优先级(0为最低)、是否循环播放(0为只播放一次,-1为无限循环)、播放速率(取值为0.5-2.0,其中1.0为正常速率)。
  • setVolume:设置指定编号音频的音量大小。
  • setPriority:设置指定编号音频的优先级。
  • setLoop:设置指定编号的音频是否循环播放。
  • setRate:设置指定编号音频的播放速率。
  • pause:暂停播放指定编号的音频。
  • resume:恢复播放指定编号的音频。
  • autoPause:暂停所有正在播放的音频。
  • autoResume:恢复播放所有被暂停的音频。
  • stop:停止播放指定编号的音频。
  • release:释放所有音频资源。
  • setOnLoadCompleteListener:设置音频加载完毕的监听器。需实现接口OnLoadCompleteListener的onLoadComplete方法,该方法在音频加载结束后触发。
视频播放

本节介绍视频播放的相关技术,首先说明视频视图的工作原理,并结合拖动条实现简单的视频播放器,接着阐述媒体控制条的用法,以及媒体控制条与视频视图的两种绑定方式,最后演示了如何实现自定义样式的视频播放控制条。

视频视图VideoView

第9章在介绍录像放映功能时使用了MediaPlayer结合SurfaceView播放视频文件,其中通过SurfaceView显示视频的画面,通过MediaPlayer设置播放参数并控制视频的播放操作。不过仅仅播一个视频就得如此深入掌握技术细节未免太兴师动众了,因此Android推出了视频视图VideoView,该控件内部集成了SurfaceView和MediaPlayer,从而实现视频画面与视频操作的统一管理,为开发者进行视频开发提供便利。

下面是VideoView的常用方法说明。

  • setVideoPath:设置视频文件的路径。
  • setMediaController:设置媒体控制条的对象。
  • setOnPreparedListener:设置预备播放监听器。需实现监听器OnPreparedListener的onPrepared方法,该方法在准备播放时调用。
  • setOnCompletionListener:设置结束播放监听器。需实现监听器OnCompletionListener的onCompletion方法,该方法在结束播放时调用。
  • setOnErrorListener:设置播放异常监听器。需实现监听器OnErrorListener的onError方法,该方法在播放出现异常时调用。
  • setOnInfoListener:设置播放信息监听器。需实现监听器OnInfoListener的onInfo方法,该方法在播放需要传递某种消息时调用,如开始/结束缓冲。
  • requestFocus:请求获得焦点。该方法要在start方法前调用。
  • start:开始播放视频。
  • pause:暂停播放视频。
  • resume:恢复播放视频。
  • suspend:结束播放并释放资源。
  • seekTo:拖动视频到指定进度开始播放。
  • getDuration:获得视频的总时长。
  • getCurrentPosition:获得当前的播放位置。该方法返回值与getDuration相等时,表示播放到了末尾。
  • isPlaying:判断是否正在播放。
  • getBufferPercentage:获得已缓冲的比例。返回值在0到1之间。
    由于VideoView只是一个播放界面,本身不会显示进度条,因此实际开发中至少得给它配备一个拖动条SeekBar,一方面用来展示当前的播放进度,另一方面用来拖动播放位置。
    在VideoView的方法中,SeekBar主要用到了三个方法,第一个getDuration方法获得的总时长对应拖动条的最大进度值,第二个getCurrentPosition方法对应拖动条的当前进度值,第三个seekTo方法是在用户拖动SeekBar结束后调用。为VideoView加上SeekBar,即可实现基本的播放控制操作。
媒体控制条MediaController

使用拖动条主要完成两个播放控制功能:显示当前播放进度和拖动到指定位置播放。这两个基本功能显然不够全面,对于一个视频播放器来说,至少还得实现下列基础功能:

(1)暂停功能和暂停之后的恢复播放功能。

(2)查看视频的总时长和当前已播放的时长。

(3)快进和快退功能。

前面介绍VideoView的常用方法时提到setMediaController方法可设置媒体控制条的对象,这个媒体控制条就是MediaController,它的界面跟Windows上的播放条几乎一模一样,并支持一些基本的播放控制操作:显示当前的播放进度、拖动到指定位置播放、暂停播放与恢复播放、查看视频的总时长和已播放时长、对视频做快进或快退操作等。

下面是MediaController的常用方法说明。

  • setMediaPlayer:设置媒体播放器的对象,即VideoView对象。该方法与setAnchorView只能调用一个。
  • setAnchorView:设置绑定的主视图,其实一般是一个VideoView对象。该方法与setMediaPlayer只能调用一个。
  • show:显示媒体控制条。
  • hide:隐藏媒体控制条。
  • isShowing:判断媒体控制条是否正在显示。
  • setPrevNextListeners:设置前一个按钮与后一个按钮的点击监听器(OnClickListener)。如果没调用该方法,那么前一个按钮与后一个按钮都不会展示。
多窗口

手机屏幕允许分成多个窗口,每个任务使用一个小窗,如此才能达成多项事务并行不悖的目标。为了实现将屏幕分窗口运行的功能,可采取分屏、画中画、自定义悬浮窗等技术手段,下面分别进行详细介绍。

分屏------多窗口模式

现在的手机屏幕越来越大,使得在屏幕上同时开多个窗口不再奢侈,因此Android从7.0开始顺势推出了分屏功能,也被称作多窗口模式。比如把竖长的手机屏幕分成上下两个窗口,一边在上面的窗口中观看电影,一边在下面的窗口中聊天,可谓娱乐、工作两不误。那么分屏功能需要开发者进行哪些适配工作呢?接下来就详细阐述如何开关分屏模式,以及在编码的时候有哪些注意的地方。

相关推荐
似霰3 小时前
安卓adb shell串口基础指令
android·adb
fatiaozhang95275 小时前
中兴云电脑W102D_晶晨S905X2_2+16G_mt7661无线_安卓9.0_线刷固件包
android·adb·电视盒子·魔百盒刷机·魔百盒固件
CYRUS_STUDIO6 小时前
Android APP 热修复原理
android·app·hotfix
鸿蒙布道师6 小时前
鸿蒙NEXT开发通知工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
鸿蒙布道师6 小时前
鸿蒙NEXT开发网络相关工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
大耳猫7 小时前
【解决】Android Gradle Sync 报错 Could not read workspace metadata
android·gradle·android studio
ta叫我小白7 小时前
实现 Android 图片信息获取和 EXIF 坐标解析
android·exif·经纬度
dpxiaolong8 小时前
RK3588平台用v4l工具调试USB摄像头实践(亮度,饱和度,对比度,色相等)
android·windows
tangweiguo030519879 小时前
Android 混合开发实战:统一 View 与 Compose 的浅色/深色主题方案
android
老狼孩111229 小时前
2025新版懒人精灵零基础及各板块核心系统视频教程-全分辨率免ROOT自动化开发
android·机器人·自动化·lua·脚本开发·懒人精灵·免root开发