在 WebView 載入網頁時,若需攔截特定鏈接(如「查看完整版」)在系統預設瀏覽器中打開,而非在 WebView 內部載入,需實現 WebViewClient 的 shouldOverrideUrlLoading() 方法。
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new MyWebViewClient());
myWebView.getSettings().setJavaScriptEnabled(true); // 通常需要
myWebView.loadUrl("https://example.com");
private class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// 解析 URL 主機
Uri uri = Uri.parse(url);
String host = uri.getHost();
// 條件:特定域名或包含特定路徑
if (host != null && host.equals("www.mysite.com")) {
// 在預設瀏覽器打開
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
return true; // 表示已處理,WebView 不再載入
}
// 其他鏈接在 WebView 內載入
return false;
}
// API 24+ 建議重寫此方法
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
String url = request.getUrl().toString();
return shouldOverrideUrlLoading(view, url);
}
}
// 使用正則或路徑匹配
if (url.contains("/fullsite") || url.endsWith("?view=full")) {
// 在瀏覽器打開
return true;
}
// 在 onPageFinished 注入 JS 標記特定鏈接
webView.evaluateJavascript(
"document.querySelectorAll('a[target=\"_blank\"]').forEach(function(el) { el.dataset.external = 'true'; });",
null
);
// 隨後在 shouldOverrideUrlLoading 中無法直接獲取 DOM 屬性
// 建議:約定特定 URL scheme 或參數標識
在瀏覽器打開後,用戶返回 App 時 WebView 狀態可能重置。建議:
// Activity 中處理返回鍵
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
// 生產環境勿直接 handler.proceed(),存在安全風險
// 建議顯示警告讓用戶選擇
handler.proceed(); // 僅測試用
}
Android 11 (API 30) 起需在 AndroidManifest.xml 聲明查詢權限:
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent>
</queries>