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加载请求,判断协议类型后交给系统应用处理:
- 给你的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
相关产品推荐
相关产品推荐

