Microphone Permission — 这是应用程序访问设备麦克风所需的系统权限。它是录音、语音消息、视频通话和语音识别所必需的。根据 Apple Developer Documentation, 2024,所有使用音频采集的应用程序都必须通过系统对话框请求用户的明确同意。
主要内容
Microphone Permission 是一种隐私保护机制,用于防止未经授权从设备麦克风录制音频。移动平台将麦克风划分为最敏感的资源之一,因为声音录制可以捕获私人对话、周围环境和机密信息。
Android 将 RECORD_AUDIO 划分为危险权限,iOS 要求必须在 Info.plist 中添加 NSMicrophoneUsageDescription 键。在两个平台上,请求在运行时执行,用户可以随时通过系统设置撤销权限。系统指示器 (iOS 上的橙色圆点,Android 12+ 上的绿色指示器) 向用户表示应用程序正在使用麦克风。
根据 Pew Research Center (2024) 的研究,54% 的移动设备用户至少有一次拒绝应用程序访问麦克风。主要原因是不理解为什么应用程序需要录音。因此,开发人员必须尽可能透明地解释使用麦克风的目的。
Android 上的麦克风权限 通过在清单中声明 RECORD_AUDIO 和在应用程序代码中进行运行时请求来获取。从 Android 10 开始,对麦克风的访问还受到后台应用程序限制的调控。
第一步是在清单文件中声明 RECORD_AUDIO 权限。如果没有这个声明,运行时请求将无效,应用程序无法访问麦克风。
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT" />
CAPTURE_AUDIO_OUTPUT 是系统权限,不可用于第三方应用程序。它仅由系统应用程序用于捕获音频输出。普通应用程序只需要 RECORD_AUDIO 来从麦克风录音。
在清单中声明后,需要执行运行时请求。让我们看一个使用 AudioRecord 从麦克风录音的示例。
private val recordAudioPermission =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
if (granted) {
startRecording()
} else {
showMicrophoneExplanation()
}
}
fun startRecording() {
val sampleRate = 44100
val bufferSize = AudioRecord.getMinBufferSize(sampleRate,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT)
val recorder = AudioRecord(MediaRecorder.AudioSource.MIC,
sampleRate, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT, bufferSize)
recorder.startRecording()
// 将音频数据写入缓冲区
}
正确处理录音的生命周期非常重要。当应用程序在 Android 9 及更新版本上切换到后台模式时,系统可能会暂停从麦克风录音。从 Android 10 开始,后台访问麦克风进一步受到限制:后台应用程序无法开始录音,正在进行的录音也会被暂停。后台录音需要 MediaProjection 或带通知的 Service。
iOS 上的麦克风权限 通过 Info.plist 中的 NSMicrophoneUsageDescription 键和调用 AVAudioSession.requestRecordPermission 方法来配置。Apple 要求在请求对话框中必须说明使用麦克风的原因。
NSMicrophoneUsageDescription 键对于任何请求访问麦克风的应用程序都是必须的。没有它,应用程序尝试录音时将崩溃。
<key>NSMicrophoneUsageDescription</key>
<string>应用程序需要麦克风访问权限以录制语音备注并发送语音消息。</string>
iOS 上的麦克风访问请求通过 AVAudioSession 执行。接收到响应后,应用程序配置音频会话并开始录音。
import AVFAudio
func requestMicrophoneAccess() {
AVAudioSession.sharedInstance().requestRecordPermission { granted in
DispatchQueue.main.async {
if granted {
self.configureAudioSession()
self.startAudioRecording()
} else {
self.redirectToSettings()
}
}
}
}
private func configureAudioSession() {
let session = AVAudioSession.sharedInstance()
do {
try session.setCategory(.playAndRecord, mode: .default)
try session.setActive(true)
} catch {
print("Audio session error: \(error)")
}
}
在 iOS 14 及更新版本上,使用麦克风的应用程序会在状态栏中显示橙色指示器。用户可以看到哪个应用程序正在录音。如果应用程序在没有合理原因的情况下在后台使用麦克风,Apple 可能会拒绝更新。AVAudioSession 可以配置音频会话的类别和模式,确定应用程序在切换到后台模式时的行为。
麦克风的使用场景 在移动应用中多种多样:从简单的语音录制到复杂的实时音频流处理。
即时通讯软件和备注应用使用麦克风录制语音消息。在这种情况下,按下录制按钮时会请求 Microphone Permission。录制结束后,重要的是停止音频会话,以便其他应用程序可以使用麦克风。iOS 上的 AVAudioSession 和 Android 上的 AudioManager 管理音频聚焦。
具有语音输入的应用程序(搜索、口识、语音助手)使用麦克风与语音识别 API 结合。在 Android 上,这是来自 android.speech 的 SpeechRecognizer,在 iOS 上是来自 Speech framework 的 SFSpeechRecognizer。语音识别可能需要额外的权限来访问识别服务(Android 上的 SPEECH,iOS 上的 SFSpeechRecognizer.requestAuthorization)。
视频通话应用程序(WebRTC、Zoom、Telegram)同时请求 Microphone Permission 和 Camera Permission。在这种情况下,重要的是顺序请求两个权限,而不是同时请求,以免用户被对话框涌入。WebRTC 使用 getUserMedia 捕获音频和视频,但在移动平台上首先需要系统权限。
为了高质量录音,需要正确配置音频会话参数。在 iOS 上,.playAndRecord 类别允许同时播放和录制声音。在 Android 上,选择 AudioSource.MIC 可以从主麦克风捕获,而 AudioSource.VOICE_COMMUNICATION 优化语音通信的录音。另外,可以配置 44100 Hz 采样率和 PCM 16 位格式以达到标准 CD 质量。
在录音过程中,可能会发生系统中断:来电、闹钟、来自其他应用程序的通知。在 iOS 上,AVAudioSessionDelegate 处理 beginInterruption 和 endInterruption。在 Android 上,AudioManager.OnAudioFocusChangeListener 通知应用程序音频聚焦的丢失或恢复。正确处理中断可以在意外事件发生时保存录音并避免数据丢失。建议在丢失聚焦时暂停录音,并在恢复后通知用户后继续。
音频采集优化 包括配置采样率、缓冲区大小和编码格式。对于语音消息,44100 Hz 和单声道已足够。对于语音识别,可能需要 16000 Hz。
在 iOS 上,使用 AVAudioSession.setPreferredIOBufferDuration 配置录音延迟。较小的缓冲区减少了延迟,但增加了 CPU 负荷。在 Android 上,AudioRecord.getMinBufferSize 返回指定参数的最小缓冲区大小。建议使用不小于该最小值的缓冲区,以防止在系统负荷过高的情况下录音时丢失数据。
最佳实践 使用 Microphone Permission 的目的是提高用户信任度和符合平台要求。
在请求 Microphone Permission 之前,显示一个屏幕,解释为什么应用程序需要麦克风以及录音将如何使用。说明音频是否传输到服务器或在本地处理。如果用户理解录音不会离开设备,他们更可能同意访问。本地处理 (on-device ASR) 是获得信任的强大论据。
如果应用程序不需要后台录音,切换到后台模式时务必停止麦克风。这不仅节省电池,还可以避免用户看到录音指示器时的消极反应。在 iOS 上,使用 UIApplicationDelegate 的 applicationDidEnterBackground 方法暂停录音。在 Android 上,处理 Activity 或 Service 中的 onPause 和 onStop。
在录音期间显示自己的录音指示器(动画麦克风图标或波形)。这通知用户麦克风正在工作,并减少了消极反应的风险。Apple 和 Google 建议使用自己的 UI 元素复制系统指示器,以达到最大透明度。
常见问题
不需要,麦克风权限仅用于从麦克风 捕获音频。通过扬声器或耳机播放声音不需要 Microphone Permission。播放只需要在 iOS 上配置音频会话或在 Android 上配置 AudioTrack。
使用 ContextCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO)。该方法返回 PackageManager.PERMISSION_GRANTED 或 PERMISSION_DENIED。另外,通过 PackageManager.hasSystemFeature 检查设备上是否有麦克风。
提供替代方案:文字输入代替语音,发送消息时不附音频,无声观看视频。如果语音功能至关重要,显示一个屏幕,包含在 系统设置 中启用权限的指示和导航按钮。
从 Android 12 开始,后台应用程序无法访问麦克风。切换到后台模式时,正在进行的录音会被暂停。此外,还出现了 Privacy Chip 指示器——状态栏中的绿色图标,表示应用程序正在使用麦克风。
最常见的原因:缺少 NSMicrophoneUsageDescription 键,原因描述不具体(“为了改善服务”而非“为了录制语音消息”),在没有用户明确操作的情况下请求权限,或者在没有 合理功能 的情况下在后台使用麦克风。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。