我有一个WebView
我希望锚点标记rel=external
在Android浏览器中打开,但所有其他链接都留在WebView
。
因此,如果用户点击标记如下所示的链接,内容将在WebView
内加载:
<a href="http://example.com/">Whatever</a>
但是,如果用户点击标记如下所示的链接,则内容将在Android浏览器中加载:
<a href="http://example.com/" rel="external">Whatever</a>
这是WebViewClient
代码中的相关代码(带有注释的一位伪代码):
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (! rel=external) { // <-- That condition...how do I do that?
view.loadUrl(url);
return false;
} else {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);
return true;
}
确定是否存在rel=external
属性/值的最佳方法是以某种方式使用addJavascriptInterface()
并让JavaScript通知Java是否存在rel
属性以及价值是?
还是有更好的方法吗?
(我正在寻找一种不涉及检查URL域名的解决方案,因为有任意数量的域需要被视为内部域,我无法提前知道或在运行中轻松确定。)
答案 0 :(得分:2)
如果您不想修改现有网址,我认为原始建议的变体可能是最好的。
使用addJavaScriptInterface
添加一个类来处理外部网址加载。内部类可能如下所示:
public class JavaScriptInterface {
public void viewExternalUrl(String url) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);
return true;
}
}
当然要加上它:
webView.addJavascriptInterface(new JavaScriptInterface(), "Android");
通过loadUrl
注入JavaScript以添加点击处理程序以在加载页面后调用JavaScript界面(为简单起见使用JQuery)。您可以通过创建自定义WebViewClient
并覆盖onPageFinished
来检测网页加载完成情况。
webView.setWebViewClient(new WebViewClient() {
private static final String sJs = "javascript:" +
Uri.encode("$('a[@rel$='external']').click(function(){ Android.viewExternalUrl($(this).attr('href')); });");
@Override
public void onPageFinished(WebView view, String url) {
webView.loadUrl(sJs);
}
}
我没有测试过这些代码,但它应该可以工作,假设你在页面中加载了JQuery。如果没有,您可以在没有它的情况下提出一些JavaScript来操作DOM,或者您可以在加载JavaScript之前使用loadUrl手动加载JQuery。
请注意,此方法完全放弃使用shouldOverrideUrlLoading
答案 1 :(得分:1)
我的建议是使用一种不同的方式来指定外部URL ...一种将该信息嵌入到URL中,因此与shouldOverrideUrlLoading
函数兼容。具体来说,创建自定义方案URL并将实际页面作为参数传递:
myappname://外部URL = encoded_real_page_url
然后在shouldOverrideUrlLoading
函数中检查它是否是自定义方案URL,提取url参数,解码然后重定向。
答案 2 :(得分:1)
如果您可以控制服务器端内容,那么请务必遵循Theo的建议。由于您指示页面也应加载标准浏览器,因此请不要使用自定义方案,而是将rel=external
部分用于链接/重定向到的实际网址。
通过这样做,您可以轻松解析url
中的shouldOverrideUrlLoading(WebView view, String url)
参数,并检查上面的键/值对。我建议您将其解析为Uri
并使用getQueryParameter(key)
检查匹配rel
的值。如果它是external
,则触发意图。
它看起来像这样:
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Uri uri = Uri.parse(url);
String relValue = uri.getQueryParameter("rel");
if (relValue != null && !relValue.equals("external")) {
view.loadUrl(url);
return false;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
startActivity(intent);
return true;
}
旁注:不需要声明'else',因为你已经从'if'中的方法返回。
如果用户可以使用您的WebView访问任何网站,并且如果您对其他应用相同键/值对的网站感到偏执,则可以轻松添加其他检查以确定该网址是否位于“您的”域中