14、权限与安全:录音权限与效果控制权限、系统级效果与普通应用效果、Android 10+的隐私变更影响
说到音频效果框架,很多人第一反应是“怎么调音效”。但做了这么多年音频开发,我越来越觉得,真正让开发者头疼的,往往不是算法本身,而是权限和安全这道坎。
你想想看,一个音频效果再牛,如果拿不到录音权限,或者因为隐私策略变更导致效果链断掉,那一切等于零。今天我们就来聊聊这块“看不见的围墙”。
录音权限:第一道门槛
录音权限,说白了就是应用能不能拿到麦克风数据。在 Android 里,这事由 RECORD_AUDIO 权限控制。但这里有个坑——光声明权限还不够。
我记得有一次,一个第三方音效 App 在 Android 11 上死活拿不到音频流。查了半天,发现是 AndroidManifest.xml 里漏了 uses-permission 标签的 maxSdkVersion 属性。嗯,这个细节很容易被忽略。
<uses-permission android:name="android.permission.RECORD_AUDIO"
android:maxSdkVersion="32" />
// 运行时请求(Android 6.0+)
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.RECORD_AUDIO},
REQUEST_CODE_RECORD_AUDIO);
}
为什么要加 maxSdkVersion?因为从 Android 13 开始,录音权限的运行时模型又变了。不加这个属性,老应用在低版本上可能出兼容性问题。我个人习惯是,永远显式声明这个属性,哪怕只是写个 32。
效果控制权限:谁有资格调音效?
录音权限只是“能不能听”,效果控制权限才是“能不能改”。Android 把效果控制权限分成了两个层级:
- 普通应用:只能控制自己的音频会话(AudioSessionId)
- 系统级应用:可以控制全局音频效果,甚至修改其他应用的音效
这里有个关键点:系统级效果权限需要签名权限。具体来说,就是 android.permission.MODIFY_AUDIO_SETTINGS。普通应用也能声明这个权限,但实际效果有限。
系统级效果 vs 普通应用效果
这两者的区别,我用一个表格来说明:
| 对比项 | 系统级效果 | 普通应用效果 |
|---|---|---|
| 权限要求 | 签名权限 + MODIFY_AUDIO_SETTINGS | 仅 MODIFY_AUDIO_SETTINGS |
| 作用范围 | 全局(所有音频流) | 仅自己的 AudioSession |
| 典型场景 | 系统音效、通话降噪 | 音乐播放器均衡器 |
| 实现方式 | AudioFlinger 内部注册 | AudioEffect API |
说白了,系统级效果是“管理员权限”,普通应用效果是“普通用户权限”。你想想看,如果每个 App 都能改全局音效,那系统音频就乱套了。Android 这么设计,其实是有道理的。
Android 10+ 的隐私变更:一场地震
Android 10 开始,隐私策略发生了翻天覆地的变化。对音频效果框架来说,影响最大的有三点:
- 分区存储(Scoped Storage):音频效果配置文件不能随便读写公共目录了
- 后台麦克风访问限制:应用在后台不能录音,效果链会断
- 音频焦点变更:多应用同时使用音频效果时,冲突处理更严格
我记得在 Android 11 刚出来那会儿,我们团队的一个音效 App 在后台播放白噪音时,效果突然失效了。查了三天,才发现是后台麦克风权限被自动回收了。嗯,这个坑踩得值。
知识体系:一张图看懂权限与安全
下面这张 SVG 图,是我梳理的权限与安全核心逻辑。你可以把它当成一个“导航图”:
从这张图你能看到,权限和安全不是孤立的。录音权限和效果控制权限是两条平行线,但最终都受到 Android 10+ 隐私变更的影响。虚线部分,就是最容易出问题的地方。
避坑指南:我踩过的三个坑
最后,分享几个实战中容易踩的坑:
- 坑一:权限声明顺序——我曾经把
RECORD_AUDIO写在MODIFY_AUDIO_SETTINGS后面,结果在 Android 9 上权限请求弹窗不出现。后来发现,权限声明顺序会影响系统解析。建议把录音权限写在最前面。 - 坑二:效果链断开——Android 11 开始,如果应用进入后台超过 30 秒,系统会自动释放音频焦点。这时候效果链会断掉。我的解决方案是:用前台服务 + 低优先级音频焦点,保证效果链不断。
- 坑三:配置文件路径——分区存储之后,效果配置文件不能放在
/sdcard/下了。我一开始没注意,结果用户反馈“音效加载失败”。后来统一改用getExternalFilesDir(),问题解决。
adb shell dumpsys audio_policy 查看当前音频策略状态。这个命令能告诉你哪些效果正在运行,以及它们的权限级别。我在排查系统级效果问题时,几乎天天用这个命令。
好了,关于权限与安全,今天就聊这么多。记住一句话:权限不是限制,而是保护。理解 Android 的设计意图,你的音频效果框架才能跑得稳、跑得久。