必须用 uni.getrecordermanager + 手势容错控制:touchstart 启动录音并加 100ms 延迟校验,touchmove/touchcancel 提前 stop,isrecording 状态严格保护,onstop/onerror 重置状态,tempfilepath 按平台处理并校验文件大小。

uni-app 里怎么实现按住说话的录音 UI
直接用 uni.startRecord 不行——它不支持“按住开始、松开停止”的交互逻辑,而且 iOS 上已废弃,Android 行为也不一致。必须换方案:用 uni.getRecorderManager + 手势事件手动控制。
为什么不能只靠 touchstart / touchend 绑定录音开关
真机上容易触发失败:微信小程序基础库对 touchstart 的响应有延迟或拦截(尤其在 scroll-view 或 swiper 内),松手时 touchend 还可能丢失(比如手指滑出按钮区域)。得加容错。
- 用
touchstart启动录音,但立刻启动一个setTimeout延迟 100ms 检查是否仍在按压 - 用
touchmove监听拖出范围,提前调用recorder.stop() - 必须监听
touchcancel—— 微信里弹窗、切后台都会触发它,否则录音会卡死在后台
recorder.start() 报错 “fail recorder is running” 怎么办
这是最常踩的坑:没做状态保护。同一个 recorder 实例不能重复 start(),也不能在未 stop() 就再次 start()。iOS 尤其敏感。
- 定义一个
isRecording布尔变量,start()前先判断,true 就直接 return -
recorder.onStop回调里务必重置isRecording = false - 在
onError回调里也重置状态,否则一次失败后整个按钮就废了 - 别在
onStart里设isRecording = true—— 它不一定触发,状态要以调用动作为准
录音文件路径拿到后怎么预览或上传
recorder.onStop 返回的 tempFilePath 是临时路径,只能用于上传或 uni.playVoice,不能直接给 image 标签或存本地。而且不同平台路径格式不同:
- 微信小程序:路径是
wxfile://开头,仅限本端使用 - H5:返回的是 blob URL,需转成
File对象再上传 - App 端(iOS/Android):是本地绝对路径,可直接传给
uni.uploadFile - 上传前建议先用
uni.getFileInfo检查大小,避免用户录了 5 分钟还不知道超限
最麻烦的其实是手势和录音状态的耦合——按下去那一刻就要准备好麦克风权限、初始化 recorder、防抖、防重复,松手瞬间又要确保 stop 被执行、错误被捕获、UI 及时还原。这些细节没串起来,UI 看着像微信,实际点十次有三次没反应。









