uni.makePhoneCall仅在App和小程序有效,H5需用;App端须申请CALL_PHONE权限并处理拒绝情况;三端需条件编译或平台判断分支。

uni-app 拨打电话不能只写一个 uni.makePhoneCall 就完事——不同平台调用机制完全不同,不区分环境直接写会出错,H5 和小程序甚至根本不会触发拨号。
uni.makePhoneCall 在 App 和小程序中能用,但 H5 不生效
这个 API 是 uni-app 官方封装的跨端拨号方法,但它在 H5 环境下只是静默失败,控制台无报错,用户点按钮没反应。原因很简单:uni.makePhoneCall 依赖原生能力,而浏览器无法直接调起系统拨号界面。
- App 端(iOS/Android):调用成功后弹出系统拨号盘,填入号码
- 微信小程序:调起微信内置拨号界面(需基础库 ≥ 2.10.0)
- H5 页面:完全不响应,
success/fail回调都不会触发
所以如果你的项目要支持 H5,必须单独处理。
H5 页面必须用 <a href="tel:10086"> 协议
H5 唯一可靠的方式是使用 HTML 的 tel: 协议链接,由浏览器决定是否唤起拨号程序(iOS Safari、Android Chrome 均支持)。注意这不是 JS 调用,而是 DOM 行为。
- 必须用
<a>标签,button+@click不行 - 号码不能带空格、横线、括号等非数字字符,否则部分 Android 机型识别失败
- 建议加
rel="noopener"和target="_self"避免跳转异常
示例:
<template> <a href="tel:10086" class="dial-btn" rel="noopener" target="_self">拨打客服</a> </template>
App 端需检查并申请拨号权限(尤其 Android)
从 Android 11(API 30)开始,plus.dial 或底层拨号行为可能被系统拦截,即使你写了调用代码,也会静默失败。必须显式申请 android.permission.CALL_PHONE 权限,并在用户拒绝后引导去设置页。
- 在
manifest.json的 “Android 设置” → “权限配置” 中勾选 “拨打电话” - 运行时用
uni.getSystemInfoSync().platform === 'android'判断平台 - 调用前建议先用
uni.authorize({scope: 'scope.callPhone'})检查权限(注意:该 scope 在 H5 无效,在 iOS 上仅作兼容占位) - 若拒绝,用
uni.openSetting()跳转权限设置页——这是安卓用户点击后仍无反应的最常见原因
小程序里 wx.makePhoneCall 已被 uni 封装替代,别混用
虽然微信原生有 wx.makePhoneCall,但在 uni-app 项目中应统一使用 uni.makePhoneCall。两者参数结构一致,但混用可能导致编译警告或真机异常(尤其在分包或插件场景下)。
- 不要在
uni-app项目里写wx.makePhoneCall,哪怕只跑小程序 -
phoneNumber字段必须是字符串,且只含数字;传数字类型(如10086)会触发fail回调 - 务必写
fail回调捕获错误,常见错误码:errCode: 1001(用户取消)、errCode: 1002(系统拒绝,多因权限或格式问题)
示例:
uni.makePhoneCall({
phoneNumber: '10086',
success: () => console.log('拨号已唤起'),
fail: (err) => console.error('拨号失败', err)
});
真正容易被忽略的是:H5 和 App 权限逻辑完全隔离,一套代码想三端通吃,必须用条件编译或运行时平台判断做分支;而安卓拨号权限一旦被用户“永久拒绝”,uni.authorize 会直接返回失败,此时只能靠 uni.openSetting 强制跳转——这点很多开发者测试时用模拟器没遇到,上线后才发现大量用户点不动。










