uni.makephonecall 在 app 端不能直接拨打,仅预填号码并唤起系统拨号盘;android 需配置权限、动态申请 call_phone、清洗号码(保留数字及+),h5 不支持,小程序需用 open-type="tel"。

uni.makePhoneCall 在 App 端是否真能“直接拨打”
不能。它只预填号码并唤起系统拨号盘,用户仍需手动点击「拨打」按钮——这是 iOS 和 Android 系统级限制,不是 uni-app 能绕过的。所谓“直接拨打”,在合规前提下仅指自动跳转到拨号界面并填入号码,而非免交互自动呼出。
Android 上静默失败的三个关键原因
很多开发者写了 uni.makePhoneCall 却没反应,不是代码错了,而是被系统拦了。常见卡点如下:
- manifest.json 里没勾选「拨打电话」权限(Android 设置 → 权限配置)
- Android 11+(API 30)起,
plus.dial或底层拨号行为默认被拦截,必须显式申请android.permission.CALL_PHONE - 用户首次拒绝授权后,不调用
uni.openSetting()引导设置页,后续调用全静默失败
建议在调用前加一层检查:uni.authorize({scope: 'scope.callPhone'}),注意该 scope 在 H5 无效、iOS 仅作占位,仅对 Android 生效。
号码格式不合法导致无提示失败
uni.makePhoneCall 对 phoneNumber 参数极其敏感:含空格、短横线、括号、中文字符(如“-”、“(”、“ ”)时,部分 Android 机型(尤其华为 EMUI、小米 MIUI)会直接静默退出,控制台无报错、success/fail 回调都不触发。
清洗逻辑建议用正则:phoneNumber.replace(/[^0-9+]/g, ''),确保只保留数字和开头的 +(用于国际号,如 +8613812345678)。不要依赖用户输入原样传入。
H5 和小程序不能共用同一套逻辑
想一套代码打天下?不行。uni.makePhoneCall 在 H5 端完全不生效,既不报错也不回调;微信小程序虽支持,但要求基础库 ≥ 2.10.0,且必须用 button 组件的 open-type="tel" 才最稳定(比 JS 调用更可靠)。
App 端真正需要关注的是权限流和号码清洗——这两处一旦漏掉,用户点按钮就像点了空气。其他平台要么走协议(H5 的 tel:)、要么走组件属性(小程序的 open-type),和 App 的原生能力路径完全不同。











