You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中launchUrl调用tel协议无法直接拨号求助

Flutter 跨平台直接拨号解决方案

要实现无需手动点击的直接拨号,核心是配置对应平台的权限,再配合launchUrl实现统一调用,无需单独做平台判断。

1. 配置平台权限

Android 端

在android/app/src/main/AndroidManifest.xml中添加拨号权限:

<uses-permission android:name="android.permission.CALL_PHONE" />

Android 6.0+ 属于危险权限,需要动态申请(后续代码会处理)。

iOS 端

在ios/Runner/Info.plist中添加权限说明(iOS 要求必须声明权限用途):

<key>NSCallerUsageDescription</key>
<string>需要直接拨打电话以完成服务操作</string>

2. 统一实现代码

先添加permission_handler包(用于动态申请权限),然后编写通用拨号函数:

import 'package:permission_handler/permission_handler.dart';
import 'package:url_launcher/url_launcher.dart';
import 'dart:io';

Future<void> makeDirectCall(String phoneNumber) async {
  // 动态申请对应平台的拨号权限
  PermissionStatus permissionStatus;
  if (Platform.isAndroid) {
    permissionStatus = await Permission.phone.request();
  } else if (Platform.isIOS) {
    permissionStatus = await Permission.callLogs.request();
  } else {
    permissionStatus = PermissionStatus.granted;
  }

  if (permissionStatus.isGranted) {
    final Uri callUri = Uri.parse('tel:$phoneNumber');
    // 使用外部非浏览器应用模式启动,确保直接触发拨号
    if (!await launchUrl(callUri, mode: LaunchMode.externalNonBrowserApplication)) {
      throw Exception('无法发起拨号请求');
    }
  } else {
    // 权限被拒绝时,引导用户打开应用设置
    await openAppSettings();
  }
}

为什么之前的代码无效?

  • Android 端:未申请CALL_PHONE权限时,系统仅允许打开拨号器填充号码,无法直接发起呼叫;
  • iOS 端:未在Info.plist中添加权限描述时,tel:协议会被限制为仅打开拨号界面,无法直接拨号。

内容的提问来源于stack exchange,提问作者Mervin Hemaraju

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 02:50:09