扫码成功后播放声音提示需满足触发时机可控、音频加载可靠、多端行为一致,应使用uni.createinneraudiocontext()在success回调中创建并播放本地mp3文件,同时配置ios audio权限和android媒体音量权限。

扫码成功后播放声音提示,核心在于「触发时机可控 + 音频加载可靠 + 多端行为一致」。uni-app 本身不提供扫码音效 API,必须手动集成音频播放逻辑,且不能依赖系统默认音效(iOS/Android 均不开放该能力)。下面分三块说清楚怎么做、为什么这么选、容易卡在哪。
扫码回调里立即调用 uni.createInnerAudioContext()
扫码成功是明确的同步事件,uni.scanCode 的 success 回调就是唯一可靠入口。此时创建音频实例并调用 play(),是最直接的链路。
- 必须用
uni.createInnerAudioContext(),不是wx.createInnerAudioContext()(微信小程序专属)或new Audio()(H5 不稳定,App 端不支持) - 音频文件建议放
/static/sound/scan_success.mp3,MP3 格式兼容性最好,大小控制在 300KB 以内 - 不要在
success外提前创建 audio 实例——App 端若在后台或未激活状态,src赋值可能失败 - 示例代码片段:
uni.scanCode({
success: (res) => {
const audioCtx = uni.createInnerAudioContext();
audioCtx.src = '/static/sound/scan_success.mp3';
audioCtx.play();
audioCtx.onEnded(() => audioCtx.destroy());
audioCtx.onError((err) => console.error('音频播放失败:', err.errMsg));
}
});
Android 和 iOS 静音模式下没声音?关键看系统设置和音频上下文
iOS 静音开关、Android 媒体音量为 0,都会导致 play() 无声但无报错。这不是代码 bug,而是平台限制,需从两方面应对:
- iOS:必须在
manifest.json → app-plus → distribute → ios → capabilities中勾选audio,否则静音模式下完全无法触发音频 - Android:8.0+ 需确保用户已授予「媒体音量」权限(非录音权限),且 App 进程未被系统强杀;可加一层容错:
audioCtx.volume = 1显式设满音量 - 避免用
wx.playBackgroundAudio():它已被微信标记为即将废弃,且在 uni-app 的非微信平台(如 App 端)不可用
为什么不用服务端推送或 TTS 动态生成?
扫码是毫秒级交互,TTS 接口延迟(通常 300–800ms)、网络失败、token 限流、语音合成失败等任一环节都会打断体验。而收款/核销类场景对“即时反馈”极其敏感。
- 预置本地音频文件是唯一满足「确定性 + 低延迟 + 离线可用」的方案
- 若需播报动态内容(如“扫描成功,金额 29.9 元”),必须走 TTS 插件(如微信同声传译插件),但要接受首次加载白屏、iOS 需额外申请语音识别权限、Android 需预装 TTS 引擎等代价
- 不推荐用
uni.showToast配合震动替代——震动在 iOS 上需用户主动开启「辅助触控」,且无声音反馈就失去核心提示意义
真正难的不是播放那行 play(),而是让声音在任意机型、任意系统设置、任意 App 生命周期状态下都“响得出来”。本地音频 + 正确上下文初始化 + 平台能力显式声明,这三者缺一不可。尤其注意 iOS 的 capabilities 配置和 Android 的音量通道判断,漏掉任何一个,扫码后就只剩沉默。











