App端收不到短信自动填充因uni-app无原生监听能力,iOS限制严格、Android需权限与前台活跃,推荐使用插件市场「sms-autofill」,其封装SmsRetrieverClient和Universal Links机制实现合规自动填。

App端为什么收不到短信自动填充?
uni-app 官方不提供原生短信监听能力,uni.getClipboard 和 uni.onKeyboardHeightChange 都无法触发短信读取。iOS 系统限制严格,Android 则需权限 + 前台 Activity 活跃 + 正确的 SMS intent 过滤。很多开发者直接在 onShow 里轮询剪贴板,结果要么拿不到(iOS 不允许)、要么拿到乱码(Android 多条短信混在一起)、要么被系统杀后台后失效。
- 必须使用原生插件,不能纯 JS 实现
- iOS 仅支持
ASAuthorizationController的「密码自动填充」(非短信),真正短信监听需依赖第三方 SDK(如腾讯云、极光)或自研 Native 模块 - Android 需动态申请
READ_SMS权限(Android 10+ 已废弃,必须降级 targetSdkVersion ≤ 28 或改用ROLE_SMS+NotificationListener方案)
推荐方案:用 uni-app 插件市场里的「sms-autofill」插件
这个插件封装了 Android 的 SmsRetrieverClient(无需读取权限)和 iOS 的「短链接 + Universal Links」回传机制,是目前最接近“自动填”的合规方案。
- 插件地址在 HBuilderX 插件市场搜
sms-autofill,安装后需在manifest.json中配置 Android 包名与签名 SHA-256(用于 Google 的 SMS Retriever API) - iOS 端必须配置
Associated Domains并部署apple-app-site-association文件,否则无法回调 - 调用方式统一:
uni.$sms.startListening(),监听成功后通过uni.$sms.on('received', callback)拿到验证码 - 注意:Android 上必须确保短信内容含特定格式,例如「【你的App名称】您的验证码是123456,5分钟内有效。」——其中「【】」和「验证码是」为默认匹配关键词,可配置但不可省略
常见失败原因和绕过技巧
-
startListening 返回 success 但没触发 received 回调?检查短信是否被系统归类为「推广」或「拦截」——Android 厂商 ROM(如华为、小米)会静默过滤,建议在短信开头加空格或特殊符号干扰识别逻辑
- iOS 模拟器完全不工作,真机调试时若
onReceived 不触发,大概率是 apple-app-site-association 文件未正确部署(无 MIME 类型、没放根目录、HTTPS 不可信、JSON 格式错误)
- Android 12+ 上
SmsRetrieverClient 有时首次启动失败,可加一层重试:setTimeout(() => uni.$sms.startListening(), 800)
- 不要试图在
onHide 后继续监听 —— App 进入后台后 Android 会立刻断开监听,iOS 更是直接终止进程
替代方案:放弃自动读取,改用「粘贴板 + 短信通知栏监听」组合
startListening 返回 success 但没触发 received 回调?检查短信是否被系统归类为「推广」或「拦截」——Android 厂商 ROM(如华为、小米)会静默过滤,建议在短信开头加空格或特殊符号干扰识别逻辑 onReceived 不触发,大概率是 apple-app-site-association 文件未正确部署(无 MIME 类型、没放根目录、HTTPS 不可信、JSON 格式错误) SmsRetrieverClient 有时首次启动失败,可加一层重试:setTimeout(() => uni.$sms.startListening(), 800) onHide 后继续监听 —— App 进入后台后 Android 会立刻断开监听,iOS 更是直接终止进程 如果插件适配成本太高,或需要兼容老旧 Android 设备,可以退一步:
- 在获取验证码后,主动调用
uni.setClipboardData写入占位符(如"[SMS_CODE_PLACEHOLDER]"),再引导用户点击输入框唤起键盘,触发系统粘贴建议 - Android 端配合
uni.getProvider拿到notification模块,监听通知栏含「验证码」字样的消息(需开启通知使用权),再正则提取数字 —— 这招在 OPPO、vivo 上比剪贴板更稳定 - 所有方案都绕不开一点:iOS 真正的「短信自动填充」只对密码字段生效(
input[type="password"]+autocomplete="one-time-code"),uni-app 的input组件目前无法透出该属性,得靠自定义原生组件桥接
实际项目里,90% 的「自动读取失败」问题出在签名配置或短信模板格式上,而不是代码逻辑。先确认插件文档里要求的 SHA-256 和域名配置项有没有漏掉一个字符,比反复改 JS 有用得多。


















