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

WebView应用mailto与tel链接点击报错net::ERR_UNKNOW_URL_SCHEME求解决

解决WebView中tel/mailto链接触发net::ERR_UNKNOWN_URL_SCHEME错误的方案

嘿,这个问题我之前帮不少开发者踩过坑!WebView默认只认http/https这类标准网页协议,碰到tel、mailto这种特殊协议就会直接抛出net::ERR_UNKNOWN_URL_SCHEME错误——本质是它不知道该怎么处理这些非标准链接。下面分Android和iOS两个平台给你具体的解决办法:

Android 端处理方式

核心思路是拦截WebView的URL加载请求,判断协议类型后交给系统应用处理:

  1. 给你的WebView设置自定义WebViewClient,重写shouldOverrideUrlLoading方法:
webView.setWebViewClient(new WebViewClient() {
    // Android 7.0+ 版本用这个重载方法
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
        String url = request.getUrl().toString();
        handleNonStandardScheme(url);
        return super.shouldOverrideUrlLoading(view, request);
    }

    // 兼容Android 7.0以下版本
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        handleNonStandardScheme(url);
        return super.shouldOverrideUrlLoading(view, url);
    }

    // 统一处理特殊协议的方法
    private void handleNonStandardScheme(String url) {
        // 处理电话链接
        if (url.startsWith("tel:")) {
            Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
            startActivity(dialIntent);
        }
        // 处理邮件链接
        else if (url.startsWith("mailto:")) {
            Intent mailIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse(url));
            startActivity(mailIntent);
        }
        // 如果有其他协议(比如sms、geo),可以在这里继续扩展
    }
});

注意:用ACTION_DIAL不需要申请CALL_PHONE危险权限,因为只是跳转到系统拨号界面,由用户手动发起通话;如果直接用ACTION_CALL才需要权限,不推荐这么做。

iOS 端处理方式

iOS中使用WKWebView(推荐)的话,通过WKNavigationDelegate拦截请求,逻辑和Android类似:

// 先给WebView设置delegate
webView.navigationDelegate = self

// 实现WKNavigationDelegate的方法
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    guard let url = navigationAction.request.url else {
        decisionHandler(.allow)
        return
    }

    guard let scheme = url.scheme?.lowercased() else {
        decisionHandler(.allow)
        return
    }

    switch scheme {
    case "tel":
        // 跳转到系统拨号界面
        if UIApplication.shared.canOpenURL(url) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        }
        decisionHandler(.cancel) // 取消WebView的加载请求
    case "mailto":
        // 跳转到邮件应用
        if UIApplication.shared.canOpenURL(url) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        }
        decisionHandler(.cancel)
    default:
        // 标准http/https协议交给WebView处理
        decisionHandler(.allow)
    }
}

提示:如果还在使用旧的UIWebView(Apple已不推荐),可以重写webView(_:shouldStartLoadWith:navigationType:)方法,逻辑完全一致。

通用注意事项

  • 不管哪个平台,处理特殊协议后记得取消WebView自身的加载请求,否则会继续触发错误。
  • 可以根据需求扩展更多协议的处理,比如sms:(短信)、geo:(地图定位)等,只要按照相同的判断逻辑添加即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:08:46