18、权限与麦克风:RECORD_AUDIO权限、录音权限、语音识别权限
麦克风权限,说白了就是让你的App能「听见」用户说话。这个权限在Android里属于危险权限,必须运行时动态申请。我见过太多App因为没处理好这个权限,要么闪退,要么录音文件全是静音。
今天我们就来彻底搞懂RECORD_AUDIO权限,以及它背后的录音和语音识别场景。
18.1 RECORD_AUDIO权限的本质
RECORD_AUDIO权限定义在AndroidManifest里,但光声明是不够的。从Android 6.0开始,这个权限需要运行时弹窗让用户授权。
<uses-permission android:name="android.permission.RECORD_AUDIO" />
嗯,这里要注意:如果你只是声明了权限,但没在代码里动态申请,直接调用MediaRecorder.start(),那就会直接抛异常。我曾经在项目里踩过这个坑——测试机是Android 5.0没问题,一换到Android 10就崩了。
18.2 录音权限的申请流程
录音权限的申请,和相机、位置权限流程一样。但有个细节:麦克风权限通常和存储权限一起申请,因为录音文件要保存到本地。
核心流程:
- 检查权限是否已授予
- 如果未授予,调用requestPermissions()
- 在onRequestPermissionsResult()中处理结果
- 如果用户拒绝,可以解释为什么需要这个权限
// 检查权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED) {
// 申请权限
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.RECORD_AUDIO},
REQUEST_CODE_RECORD_AUDIO);
} else {
// 权限已授予,开始录音
startRecording();
}
我个人习惯把权限申请封装成一个工具类,这样多个页面复用起来方便。你想想看,如果每个Activity都写一遍权限回调,代码会变得很臃肿。
18.3 语音识别权限的特殊性
语音识别(SpeechRecognizer)除了需要RECORD_AUDIO权限,还需要INTERNET权限。为什么?因为Android的语音识别默认走Google服务,需要联网把音频数据发到云端处理。
| 权限 | 用途 | 是否必须 |
|---|---|---|
| RECORD_AUDIO | 捕获麦克风音频流 | 是 |
| INTERNET | 连接语音识别服务 | 是(在线识别) |
| ACCESS_NETWORK_STATE | 检查网络状态 | 推荐 |
避坑指南:我曾经遇到过一个Bug——语音识别在WiFi下正常,切换到移动网络就失败。后来发现是没处理网络切换时的重连逻辑。建议在开始语音识别前,先检查网络可用性。
18.4 录音权限的避坑指南
这里我总结几个实际项目中容易踩的坑:
- 权限被永久拒绝:用户勾选了「不再询问」后,再次申请不会弹窗。这时候应该引导用户去设置里手动开启。
- 多权限同时申请:如果同时申请麦克风和存储权限,用户可能只同意其中一个。代码里要分别检查每个权限的状态。
- 后台录音限制:Android 9+限制了后台App访问麦克风。如果你的App需要在后台录音,得用前台服务。
小技巧:在申请权限前,先调用shouldShowRequestPermissionRationale()判断是否需要向用户解释。如果用户之前拒绝过,弹个Dialog说明用途,成功率会高很多。
18.5 知识体系图
下面这张图展示了麦克风权限相关的完整知识结构:
18.6 实际项目中的最佳实践
最后分享几个我在项目里沉淀下来的经验:
- 权限申请时机:不要一进App就弹权限,等用户真正要录音的时候再申请。这样用户更容易理解为什么需要这个权限。
- 权限状态缓存:每次启动录音前都检查权限状态,不要只检查一次就缓存结果。因为用户可能去设置里关闭了权限。
- 降级方案:如果用户拒绝麦克风权限,可以考虑用「文字输入」作为替代方案。别直接让功能不可用。
总结一下:RECORD_AUDIO权限是Android运行时权限体系里比较典型的一个。掌握了它的申请流程、避坑点和最佳实践,其他危险权限的处理思路也大同小异。嗯,核心就是——尊重用户的选择,同时保证功能可用。
公众号:蓝海资料掘金营,微信deep3321