微信小程序必须用uni.getBackgroundAudioManager(),因其是独立于页面生命周期的原生后台音频服务,支持锁屏控制;而uni.createInnerAudioContext()属页面级音频上下文,切后台后JS暂停、监听器失效、实例可能被销毁,无法响应系统控制。

微信小程序必须用 uni.getBackgroundAudioManager(),其他平台(支付宝、字节、H5)不支持后台音频控制,强行监听无意义。
为什么 uni.createInnerAudioContext() 不能监听锁屏/后台控制
它本质是页面级音频上下文,生命周期绑定在当前页面。切后台后,JS 执行被暂停、事件监听器自动失效,onPlay、onPause 等回调全部停止触发。iOS 微信甚至会直接销毁该实例,控制台可能连错误都不报。
常见错误现象:
- 调用
audio.onPlay(() => console.log('playing')),切后台后再切回,发现日志没打印,也不再触发 - 误以为加了
audio.loop = true就能后台续播 —— 实际上 loop 只在前台生效,后台一挂就停 - 在
onHide里手动audio.pause(),但用户从锁屏界面点播放键,音频毫无反应
uni.getBackgroundAudioManager() 的正确初始化顺序
这个 API 是微信原生提供的独立音频服务,不依赖页面 JS 生命周期,才能响应锁屏控制条、耳机按键、系统通知栏操作。但它有硬性初始化条件,漏一步就静音或无响应。
实操建议:
- 必须在用户首次交互(如按钮点击)之后调用
play(),不能在onLoad或onShow自动触发 -
title、singer、epname至少填其中两个,否则 iOS 锁屏界面不显示控制条(只显示“未知”) -
coverImgUrl必须是 HTTPS 图片,且尺寸建议 ≥ 300×300,否则 Android 微信通知栏缩略图模糊或不显示 - 设置
src后必须显式调用manager.play(),仅赋值src不会加载或播放
示例片段:
const manager = uni.getBackgroundAudioManager();
manager.title = '春日序曲';
manager.singer = '李四';
manager.coverImgUrl = 'https://cdn.example.com/cover.jpg';
manager.src = 'https://cdn.example.com/song.mp3';
// 在按钮 click 回调中执行
buttonClick() {
manager.play().catch(e => console.error('play failed:', e));
}
监听后台播放状态变化的可靠方式
不要依赖页面生命周期钩子(如 onHide/onShow),它们和音频实际状态不同步。真正反映用户操作的是 manager 自身事件。
必须监听的三个事件:
-
manager.onPlay():用户从锁屏/通知栏点“播放”,或调用play()成功时触发 -
manager.onPause():用户点暂停键、切到其他 App、或系统因资源紧张中断时触发 -
manager.onStop():用户点“停止”、或调用stop()时触发(注意:这不是播放自然结束)
容易踩的坑:
- 误把
onEnded当作后台停止信号 —— 它只在音频播完才触发,后台中断不会触发它 - 在
onPause里立即调用manager.play()尝试“自动续播”,但微信会拒绝(防止滥用) - 未区分主动暂停(用户点暂停)和被动中断(微信语音抢占),导致 UI 状态错乱
支付宝/字节/快应用等平台怎么处理
这些平台没有 BackgroundAudioManager 对应能力,uni.createInnerAudioContext() 切后台后必然中断,且无法恢复。所谓“监听控制”纯属空谈。
可行做法:
- 用
uni.getSystemInfoSync().platform明确判断平台,微信走getBackgroundAudioManager,其他平台直接隐藏锁屏控制相关 UI 元素 - 在播放页顶部加一行提示:“离开小程序后音乐将暂停”,避免用户预期落差
- 若业务强依赖后台播放(如课程音频),需在启动页或登录后明确引导用户使用微信小程序
不要尝试用 setInterval + manager.seek() 模拟续播 —— 切后台后 JS 定时器基本失效,iOS 尤其严格。
最易被忽略的一点:微信后台音频的“继续播放”行为,只对同一 src 生效。如果用户中途切换歌曲,新 src 需要重新触发一次用户手势(比如再点一次播放按钮),否则锁屏界面控件会灰掉,无法响应。


















