Android WebView如何打开tel:等自定义URL Scheme链接?
解决Android WebView唤起拨号器/WhatsApp等应用的方案
问题原因
- 现有代码仅处理了
tel:和mailto:协议,未覆盖whatsapp:等其他自定义URL Scheme。 - 页面中存在纯数字号码链接(如
8806288365),WebView会将其视为普通网页URL加载,导致net::ERR_UNKNOWN_URL_SCHEME错误。
修复后的完整代码
class WebViewClientDemo extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { Context context = view.getContext(); // 处理纯数字号码(无tel:前缀) if (url.matches("^\\d+$")) { Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + url)); startIntentSafely(context, dialIntent); return true; } // 处理tel:协议 if (url.startsWith("tel:")) { Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse(url)); startIntentSafely(context, dialIntent); return true; } // 处理whatsapp:协议 if (url.startsWith("whatsapp:")) { Intent whatsappIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); startIntentSafely(context, whatsappIntent); return true; } // 处理mailto:协议 if (url.startsWith("mailto:")) { Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse(url)); startIntentSafely(context, emailIntent); return true; } // 其他HTTP/HTTPS链接在WebView内加载 if (url.startsWith("http://") || url.startsWith("https://")) { view.loadUrl(url); return true; } // 兜底:处理其他未覆盖的自定义Scheme Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); if (startIntentSafely(context, intent)) { return true; } // 无法处理的链接,返回false让系统处理 return false; } // 适配API 24+的重载方法 @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { String url = request.getUrl().toString(); return shouldOverrideUrlLoading(view, url); } /** * 安全启动Intent,避免因无对应应用导致崩溃 */ private boolean startIntentSafely(Context context, Intent intent) { if (intent.resolveActivity(context.getPackageManager()) != null) { context.startActivity(intent); return true; } // 可选:提示用户未安装对应应用 Toast.makeText(context, "未找到对应应用", Toast.LENGTH_SHORT).show(); return false; } }
关键优化点
- 纯数字号码处理:通过正则匹配
^\\d+$,将纯数字转换为tel:协议链接,避免WebView误判为网页。 - 扩展Scheme支持:新增
whatsapp:协议的处理逻辑,可按需添加其他协议(如sms:、tg:等)。 - 安全启动Intent:通过
resolveActivity检查是否有应用能处理该Intent,防止崩溃。 - 版本适配:实现API 24+的
shouldOverrideUrlLoading重载方法,覆盖所有版本的链接拦截逻辑。 - HTTP/HTTPS单独处理:明确区分网页链接和自定义Scheme,避免错误拦截正常网页。
内容的提问来源于stack exchange,提问作者SHUBHAM SAWANT
相关产品推荐
相关产品推荐

