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)
方法,其中参数 audioSource 是int
类型的标志位,其值通常设置为麦克风的音频源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
多媒体录制类的相关使用将会更加实用。
Android系统编程入门系列之硬件交互——多媒体麦克风的更多相关文章
- Android系统编程入门系列之硬件交互——多媒体摄像头
多媒体系列硬件 多媒体包括图片.动画.音频.视频,这些多媒体素材的采集(输入)主要依靠摄像头和麦克风等硬件设备转化为基础数据,而他们的播放渲染(输出),则需要依靠具有相关功能的编解码软件.当然随着硬件 ...
- Android系统编程入门系列之硬件交互——多媒体展示
前两篇文章通过麦克风硬件和摄像头硬件分别采集音频和视频的多媒体数据,在得到的多媒体数据通常是以编码文件的格式存储,在用户需要展示时,可通过设备的内置扩音器或蓝牙耳机等硬件播放音频,通过设备的显示屏或外 ...
- Android系统编程入门系列之硬件交互——传感器
到目前为止,关于应用程序与用户之间的相关内容便比较肤浅的大致介绍完毕.而在整个系统架构中,应用程序与用户之间的交互,犹如参天大树上的枝干和树叶,交互起来五彩缤纷,但使整个生态系统保持生命力的核心,在于 ...
- Android系统编程入门系列之硬件交互——通信硬件USB
在硬件交互的首篇对设备硬件的分类中,互联通信系列硬件主要用来与其他设备进行数据交互.从本文开始,将重点介绍该系列相关硬件. 互联通信系列硬件 根据硬件的可通信距离,由近及远分为USB.NFC.蓝牙.W ...
- Android系统编程入门系列之硬件交互——通信硬件Bluetooth
通信硬件NFC的文章,虽然可以在Android系统中通过非直接接触的形式与支持NFC硬件的设备通信,但是也只能交互一些简短的标签内容,对大量的持续性数据,却并不能很好的支持.因此针对这个弊端,可以考虑 ...
- Android系统编程入门系列之硬件交互——通信硬件NFC
在上篇文章介绍了接入式USB硬件的简单使用,接下来将介绍不依赖物理连接的硬件通信了.本文的重点是近距离通信的硬件NFC. NFC硬件 应用程序中可以通过NFC硬件读取或发送指定协议的技术实现,在And ...
- Android系统编程入门系列之硬件交互——无线通信WLAN
Android系统的移动设备大多支持无线WLAN技术.利用该技术,不仅能实现互联网通信,还能实现无线定位,热点共享等远程通信功能.针对使用WLAN的不同功能,可能需要分别申请不同的权限声明,同时调用不 ...
- Android系统编程入门系列之硬件交互——通信硬件电信SIM卡
现在的SIM卡通常具备基站定位.语音通话.短信消息.网络流量这四大功能,而在移动端是无法对SIM卡使用基站定位功能的,所以这里只介绍移动端如何使用SIM卡实现语音通话.短信消息.数据流量三个功能. 语 ...
- Android系统编程入门系列之加载界面Activity
上回说到应用初始化加载及其生命周期,在Android系统调用Applicaiton.onCreate()之后,继续创建并加载清单文件中注册的首个界面即主Activity,也可称之为入口界面.主Acti ...
随机推荐
- Python | 实现pdf文件分页
不知道大家有没有遇到过这么一种情况,就比如一个pdf格式的电子书,我们经常浏览的是其中的一部分,而这电子书的页数很大,每当需要浏览时,就需要翻到对应的页码,就有点儿繁琐. 还有一些情况,比如,我们想分 ...
- jQuery常用验证
1.文本框不能为为空 if ($("#RushStartTime").val() == "") { alert("请输入该产品.."); $ ...
- Bzoj通过5题纪念
我A了五题啦!!!
- Linux&C open creat read write lseek 函数用法总结
一:五个函数的参数以及返回值. 函数 参数 返回值 open (文件名,打开方式以及读 ...
- SpringBoot2.x请求注解简单介绍(4)
1.新建项目,项目中实战讲解注解作用 2.pom.xml依赖配置 <properties> <project.build.sourceEncoding>UTF-8</pr ...
- leetcode 剪绳子系列
### 剪绳子一 利用动态规划 状态转移方程 为啥是这个样子?首先 代表 长度为i的绳子被剪去j,且继续剪(子问题) 表示长度为i的绳子被剪去j,不剪了的乘积 注意初始化: n<2 f=0 ...
- 关于 better-scroll 设置了以后无法滚动或不生效的问题
首先在mounted里面注册组件 例:let scroll = new BScroll("#commondityLeftList") 然后打印实例化对象,例:console. ...
- LeetCode 199. 二叉树的右视图 C++ 用时超100%
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode ...
- Vue的第一课
终于学习到Vue了,美滋滋,给自己点个赞 前后端作用: 1.1vs1(一个Vue对象控制一个) <body> <div id="app"> <p> ...
- nio实现文件夹内容的监听
参考的博客 package com.jp.filemonitor; import java.io.IOException; import java.nio.file.FileSystems; impo ...