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

Flutter中如何实现点击手机号弹出通话类应用选择列表的功能?

Flutter 点击手机号弹出多通话渠道选择实现方案

核心思路

不用依赖flutter_launcher的单一通话能力,通过官方维护的url_launcher库调用各通话应用的URL Schema,配合系统自带的底部弹窗组件实现选项选择,全平台兼容。

步骤1:配置依赖与权限

  • 安装url_launcher依赖,执行命令:
    flutter pub add url_launcher
  • 安卓权限配置:在android/app/src/main/AndroidManifest.xml的<manifest>标签(与<application>同级)下添加如下配置,避免安卓11及以上版本跳转失败:
<queries>
    <!-- 系统电话权限 -->
    <intent>
        <action android:name="android.intent.action.DIAL" />
        <data android:scheme="tel" />
    </intent>
    <!-- 注册WhatsApp包名 -->
    <package android:name="com.whatsapp" />
    <!-- 注册Skype包名 -->
    <package android:name="com.skype.raider" />
</queries>
  • iOS权限配置:在ios/Runner/Info.plist的<dict>标签下添加白名单配置:
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>tel</string>
    <string>whatsapp</string>
    <string>skype</string>
</array>

步骤2:实现点击逻辑与弹窗

直接调用系统自带的showModalBottomSheet实现选项列表,配合各应用的Schema跳转即可,示例代码如下:

import 'package:url_launcher/url_launcher.dart';

// 点击手机号时触发该方法,入参为用户选中的手机号
void _showCallOptionDialog(String rawPhone, BuildContext context) async {
  // 格式化手机号:清除非数字字符,可根据业务需求自行拼接国家码,比如国内号码加86前缀
  final cleanedPhone = rawPhone.replaceAll(RegExp(r'[^0-9]'), '');
  // 弹出底部选项列表
  await showModalBottomSheet(
    context: context,
    builder: (ctx) => SafeArea(
      child: Wrap(
        children: [
          // 系统电话选项
          ListTile(
            leading: const Icon(Icons.phone),
            title: const Text('系统电话通话'),
            onTap: () async {
              Navigator.pop(ctx);
              final telUri = Uri(scheme: 'tel', path: cleanedPhone);
              if (await canLaunchUrl(telUri)) {
                await launchUrl(telUri);
              }
            },
          ),
          // WhatsApp通话选项
          ListTile(
            leading: const Icon(Icons.call), // 可替换为WhatsApp专属图标
            title: const Text('WhatsApp通话'),
            onTap: () async {
              Navigator.pop(ctx);
              // 注意:WhatsApp跳转需要带完整国家码,比如国内号码需要拼接前缀86
              final whatsappUri = Uri.parse('whatsapp://call?phone=+$cleanedPhone');
              if (await canLaunchUrl(whatsappUri)) {
                await launchUrl(whatsappUri);
              } else {
                // 可自行添加未安装应用的提示逻辑,比如Toast提示
              }
            },
          ),
          // Skype通话选项
          ListTile(
            leading: const Icon(Icons.video_call), // 可替换为Skype专属图标
            title: const Text('Skype通话'),
            onTap: () async {
              Navigator.pop(ctx);
              final skypeUri = Uri.parse('skype:$cleanedPhone?call');
              // 如果需要发起视频通话,将uri替换为 skype:$cleanedPhone?call&video=true 即可
              if (await canLaunchUrl(skypeUri)) {
                await launchUrl(skypeUri);
              } else {
                // 可自行添加未安装应用的提示逻辑
              }
            },
          )
        ],
      ),
    ),
  );
}

注意事项

  • 每次跳转前调用canLaunchUrl做可用性校验,避免用户未安装对应应用时触发崩溃
  • WhatsApp的手机号必须带国际区号,否则无法正常识别跳转
  • 可根据业务需求扩展其他通话渠道,只要拿到对应应用的公开URL Schema即可适配

内容的提问来源于stack exchange,提问作者Darshan Prajapati

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 21:45:04