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

WebView打开WhatsApp遇net::err_unknown_url_scheme错误求助

WebView打开WhatsApp触发net::ERR_UNKNOWN_URL_SCHEME错误

问题场景

从Flutter WebView中触发用户下单后打开WhatsApp,初始打开正常,但几秒后弹出错误界面,提示net::ERR_UNKNOWN_URL_SCHEME,尝试过同类问题常规方案无效。

相关代码

链接启动方法

_launchURL(String url) async {
  await launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication);
}

WebView导航拦截处理

webViewController
  ..setNavigationDelegate(
    NavigationDelegate(
      onNavigationRequest: (NavigationRequest request) async {
        if (request.url.startsWith('https://wa.me/996996969696')) {
           List<String> urlSplitted = request.url.split("&text=");
          
          String phone = "996996969696";
          String message = urlSplitted.last.toString().replaceAll("%20", " ");

          await _launchURL("https://wa.me/$phone/?text=testText}");
          // await _launchURL("https://wa.me/$phone/?text=${Uri.parse(message)}");

          return NavigationDecision.prevent;
        } 
        return NavigationDecision.navigate;
      },
    ),
  )

Android Manifest配置

<queries>
    <intent>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="sms" />
    </intent>
    <!-- 检查通话支持 -->
    <intent>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="tel" />
    </intent>
    <!-- 打开HTTPS链接 -->
    <intent>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="https" />
    </intent>
    <!-- 拨打电话 -->
    <intent>
        <action android:name="android.intent.action.DIAL" />
        <data android:scheme="tel" />
    </intent>
    <!-- 发送短信 -->
    <intent>
        <action android:name="android.intent.action.SENDTO" />
        <data android:scheme="smsto" />
    </intent>
    <!-- 发送邮件 -->
    <intent>
        <action android:name="android.intent.action.SEND" />
        <data android:mimeType="*/*" />
    </intent>
</queries>

依赖版本

  • webview_flutter: ^4.2.0
  • url_launcher: ^6.1.12

补充尝试

移除mode: LaunchMode.externalApplication后问题依旧。


解决方案

1. 修正链接语法错误

你当前构造的WhatsApp链接末尾多了一个多余的},这会导致链接解析异常,先修正:

await _launchURL("https://wa.me/$phone/?text=testText");

2. 添加WhatsApp协议查询权限

Android 11+需要明确声明可调用的应用协议,在AndroidManifest.xml的<queries>中添加:

<intent>
    <action android:name="android.intent.action.VIEW" />
    <data android:scheme="whatsapp" />
</intent>

3. 优化链接构造与启动逻辑

直接使用whatsapp://协议构造链接(比wa.me跳转更稳定),同时增加可用性检查:

_launchWhatsApp(String phone, String message) async {
  final encodedMessage = Uri.encodeComponent(message);
  // 优先用客户端协议
  final clientUrl = "whatsapp://send?phone=$phone&text=$encodedMessage";
  // 客户端不可用时回退网页版
  final webUrl = "https://wa.me/$phone/?text=$encodedMessage";

  if (await canLaunchUrl(Uri.parse(clientUrl))) {
    await launchUrl(Uri.parse(clientUrl), mode: LaunchMode.externalApplication);
  } else {
    await launchUrl(Uri.parse(webUrl), mode: LaunchMode.externalApplication);
  }
}

// 导航拦截中调用优化后的方法
onNavigationRequest: (NavigationRequest request) async {
  if (request.url.startsWith('https://wa.me/996996969696')) {
    List<String> urlSplitted = request.url.split("&text=");
    String phone = "996996969696";
    String message = urlSplitted.last.replaceAll("%20", " ");
    
    await _launchWhatsApp(phone, message);
    return NavigationDecision.prevent;
  } 
  return NavigationDecision.navigate;
}

4. 避免WebView残留加载

确保拦截逻辑执行后,WebView不会继续加载原链接,检查return NavigationDecision.prevent是否被正确触发,可在拦截方法开头添加日志确认。

5. 清理WebView缓存

旧缓存可能导致链接解析异常,在WebView初始化时添加:

await webViewController.clearCache();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 15:43:12