uni.makePhoneCall仅在App(iOS/Android)和小程序(微信/支付宝等)有效,H5完全不生效;H5必须用协议,App需配置权限并处理拒绝,小程序需检查authSetting。
uni.makePhoneCall 在 H5 上完全不生效,这是最常被忽略的前提。直接写一个调用就上线,H5 用户点按钮毫无反应,控制台还不会报错——静默失败。
uni.makePhoneCall 在哪些平台能用?
这个 api 只在 app(ios/android)和微信/支付宝等小程序中真正起作用:
- App 端:调用后弹出系统拨号盘,填入号码(需权限)
- 微信小程序:唤起微信内置拨号界面(基础库 ≥ 2.10.0)
- H5:无任何效果,
success/fail回调都不会触发
所以「全端兼容」不是靠一个 API 堆出来,而是分平台写逻辑。
H5 页面必须用 tel: 协议链接
浏览器无法执行原生拨号,唯一可靠方式是 HTML 的 <a></a> 标签 + tel: 协议:
- 不能用
<button></button>触发 JS 调用 - 号码必须纯数字,不能含空格、横线、括号,否则部分 Android 机型识别失败(如
"400-123-4567"→ 改为"4001234567") - 建议加
rel="noopener"和target="_self"防止跳转异常
示例:
<a href="tel:4001234567" rel="noopener" target="_self">拨打客服</a>
App 端必须处理权限和拒绝路径
Android 11(API 30)起,plus.dial 或底层拨号行为会被系统拦截,即使代码写了也静默失败:
- manifest.json 中必须勾选「拨打电话」权限
- 运行时用
uni.getSystemInfoSync().platform === 'android'判断平台 - 调用前建议检查权限:
uni.authorize({scope: 'scope.callPhone'})(注意该scope在 H5 无效) - 若用户拒绝,必须调用
uni.openSetting()跳转到系统设置页——这是安卓用户点了没反应的最常见原因
微信小程序要防「首次拒绝后永久失效」
微信不会在用户拒绝后再次弹授权框,后续调用直接走 fail:
- 不要只依赖
uni.makePhoneCall的fail回调来提示「拨号失败」 - 应前置检查:
uni.getSetting获取authSetting['scope.phoneNumber'](注意字段名是phoneNumber,不是callPhone) - 若未授权,引导用户手动开启(比如弹
uni.showModal提示去「设置 > 权限管理」) - 号码传入前务必清洗:用正则
phoneNumber.replace(/[^0-9]/g, '')去除非数字字符
真正容易出问题的,从来不是「怎么写第一行代码」,而是「用户点了没反应」时你根本不知道该查哪一层——H5 没协议、App 没权限、小程序被拒过一次,三者表现一样,但根因完全不同。











