Android系统编程入门系列之硬件交互——多媒体麦克风

多媒体摄像头及相关硬件文章中,对摄像头的使用方式需要区分应用程序的目标版本以使用不同的代码流程,而与之相比,麦克风硬件的使用就简单多了。

麦克风及相关硬件

麦克风硬件在移动设备上作为音频的采集设备,由于只需要一个收声口,其颜值对用户来说关注度比较低。而且不同的麦克风硬件在性能上差距不大,其应用场景也只是在录制视频时的音频采集,或单独的音频采集,故使用流程和相关操作都比较简单易懂。

只是在目标版本为Android9.0即API 28即以上的系统中,如果应用程序想使用麦克风,必须保持前台运行,或使用前台服务以访问麦克风并采集音频。否则如果应用程序切换到后台,将无法正常使用麦克风采集的数据。

权限声明

首先对麦克风硬件的使用权限进行声明,其权限名及值为Manifest.permission.RECORD_AUDIO="android.permission.RECORD_AUDIO"。该权限必须在应用程序的清单文件中声明,并且在目标版本为Android6.0即API 23及以上的系统中还需要动态申请该权限,经用户授权后方可启用麦克风。

使用流程

关于麦克风的音频采集流程,与在API 21以下使用摄像头的流程相似。首先检测麦克风硬件,在能获取到Context上下文环境对象的位置,调用上下文环境对象的getPackageManager()方法获取android.content.pm.PackageManager包管理类的实例化对象,进而通过该对象的hasSystemFeature(String featureName)方法,使参数 featureName 值为PackageManager.FEATURE_MICROPHONE 代表麦克风功能,来判断当前系统是否有麦克风硬件的支持。

对于支持麦克风硬件的设备,在目标版本为Android9.0即API 28及以上的系统中,可以获取麦克风硬件的详细信息。可以调用上下文环境对象的getSystemService(String name)方法获取系统服务中的音频管理类,该方法的参数 name 值为Context.AUDIO_SERVICE=\"audio\",并将返回对象强制转换为android.media.AudioManager音频管理类。借助AudioManager音频管理类对象,可以访问音频采集和播放相关的信息。其中,调用该对象的getMicrophones()方法,得到返回的android.media.MicrophoneInfo类型组成的列表,而这里的MicrophoneInfo麦克风信息类对象,则对应保存了该设备上可使用的每个麦克风信息。

音频采集

对于麦克风硬件的数据采集,主要用到android.media.MediaRecorder多媒体录制类,该类在多媒体摄像头及相关硬件中实现视频录制功能时也有使用。这里也将详细说明MediaRecorder多媒体录制类的使用方式。

首先实例化多媒体录制类对象,使用MediaRecorder(Context context)构造方法。该方法的参数 context 即当前使用多媒体录制类的上下文环境对象。

在初始化MediaRecorder多媒体录制类对象后,可以调用该对象的setX系列方法设置相关配置项。
在录制音频时,需要选择音频源。设置音频源可以调用该对象的setAudioSource(int audioSource)方法,其中参数 audioSourceint类型的标志位,其值通常设置为麦克风的音频源MediaRecorder.AudioSource.MIC=1,另外还可以是适用于通话的麦克风MediaRecorder.AudioSource.VOICE_CALL=4,或者适用于现场直播的麦克风MediaRecorder.AudioSource.VOICE_PERFORMANCE=10等。
在录制音频时,麦克风采集的音频通常需要编码输出,设置编码格式可以调用该对象的setAudioEncoder(int audio_encoder)方法,其参数 audio_encoder 同样是int类型的标志位,其值可以是AMR NB格式的MediaRecorder.AudioEncoder.AMR_NB=1,AMR WB格式的MediaRecorder.AudioEncoder.AMR_WB=2,AAC LC格式的MediaRecorder.AudioEncoder.AAC=3,OGG格式的MediaRecorder.AudioEncoder.VORBIS=6,OPUS格式的MediaRecorder.AudioEncoder.OPUS=7等。
在录制音频后,可以将数据输出到文件中,设置输出音频文件可以调用该对象的setOutputFile(String path)方法,其参数 path 指定了输出文件的绝对路径。
在输出文件时同样要设置输出格式,调用该对象的setOutputFormat(int output_format)方法,其参数 output_format 同样是int类型的标志位,与音频编码格式对应,其值可以调用MediaRecorder.OutputFormat静态类的相关常量。

MediaRecorder对象设置完相关准备工作后,可以调用该对象的prepare()方法,获取相关硬件,准备开始采集音频数据。
而调用MediaRecorder对象的start()方法,则开始启动采集音频,并将数据输出到指定的文件中。

录制音频过程中,可以调用MediaRecorder对象的pause()方法暂停录制,数据将会暂停输出到指定文件。
如果想再次继续录制音频并将数据输出到文件,可以调用MediaRecorder对象的resume()方法继续录制。

最终,需要停止采集音频,调用MediaRecorder对象的stop()方法停止录制,数据将停止输出到指定文件,并关闭对指定文件的使用状态。

在停止录制后,必须调用MediaRecorder对象的release()方法,释放当前多媒体录制类所占用的资源,包括对麦克风的占用状态等。

使用麦克风的音频采集功能,还可以通过android.media.AudioRecord音频录制类实现。而且MediaRecorder多媒体录制类中关于音频录制的功能,在底层同样是通过AudioRecorder音频录制类实现的,所以初级阶段掌握MediaRecorder多媒体录制类的相关使用将会更加实用。

上一篇:十天学会单片机Day0点亮LED (锁存器、三极管、继电器)


下一篇:【二】Android MediaRecorder C++底层架构音视频处理过程和音视频同步源码分析