WebView 放弃 rel= 到活动管理器的外部链接
我有一个 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 域的解决方案,因为有任意数量的域需要被视为内部域,并且我无法提前知道或轻松即时确定。)
I have a WebView
wherein I would like anchor tags with rel=external
to open in the Android browser but all other links to stay in the WebView
.
So the content will load within the WebView
if the user taps a link whose markup looks like this:
<a href="http://example.com/">Whatever</a>
But the content will load in the Android browser if the user taps a link whose markup looks like this:
<a href="http://example.com/" rel="external">Whatever</a>
Here's my relevant code (with one bit of pseudocode identified with a comment) in the WebViewClient
code:
@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;
}
Would the best way to determine whether there is a rel=external
attribute/value be to somehow use addJavascriptInterface()
and have JavaScript inform Java whether or not there is a rel
attribute and what the value is?
Or is there a better way?
(I am looking for a solution that does not involve checking the domain of the URL because there are an arbitrary number of domains that need to be treated as internal and that I cannot know in advance or determine easily on-the-fly.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为如果您不想修改现有的 URL,那么您最初建议的变体可能是最好的。
使用
addJavaScriptInterface
添加一个类来处理外部 URL 加载。内部类可能如下所示:当然添加它:
注入 JavaScript 以添加点击处理程序,以在页面加载后通过
loadUrl
调用 JavaScript 接口(为简单起见,使用 JQuery)。您可以通过创建自定义WebViewClient
来检测页面加载完成情况 并覆盖onPageFinished
。我还没有测试过任何这段代码,但它应该可以工作,假设您在页面中加载了 JQuery。如果没有,您可能可以想出一些 JavaScript 来在没有它的情况下操作 DOM,或者您可以使用 loadUrl 在加载 JavaScript 之前先手动加载 JQuery。
请注意,此方法完全放弃了
shouldOverrideUrlLoading
的任何使用I think a variation of your original suggestion is probably best if you don't want to modify the existing URL.
Use
addJavaScriptInterface
to add a class to handle your external URL loading. An inner class might look like this:And of course adding it:
Inject JavaScript to add click handlers to call your JavaScript interface after the page is loaded (using JQuery for simplicity's sake) through
loadUrl
. You can detect the page load finishing by creating a customWebViewClient
and overridingonPageFinished
.I haven't tested any of this code, but it should work, assuming you have JQuery loaded in the page. If not, you can probably come up with some JavaScript to manipulate the DOM without it or you can use loadUrl to manually load JQuery first before the loading the JavaScript.
Note that this approach completely abandons any use of
shouldOverrideUrlLoading
我的建议是使用一种不同的方式来指定外部 URL...将该信息嵌入到 URL 中,因此与
shouldOverrideUrlLoading
函数兼容。具体来说,创建自定义方案 URL 并将真实页面作为参数传递:myappname://external?url=encoded_real_page_url
然后在
shouldOverrideUrlLoading
函数中检查它是否是自定义方案 URL,提取 url 参数,解码然后重定向。My suggestion is to use a different way of designating external URLs... one that embeds that info in the URL and hence is compatible with the
shouldOverrideUrlLoading
function. Specifically, create custom scheme URLs and pass the real page as a parameter:myappname://external?url=encoded_real_page_url
Then in the
shouldOverrideUrlLoading
function check if it's a custom scheme URL, extract the url param, decode it and then redirect.如果您可以控制服务器端内容,那么一定要遵循 Theo 提出的建议。由于您指示页面也应该在标准浏览器中加载,因此不要使用自定义方案,而应将
rel=external
作为您要链接/重定向到的实际网址的一部分。通过这样做,您可以轻松解析
shouldOverrideUrlLoading(WebView view, String url)
中的url
参数并检查上述键/值对。我建议您将其解析为Uri
并使用getQueryParameter(key )
检查匹配rel
的值。如果是外部
,则触发一个 Intent。它看起来像这样:
旁注:不需要声明“else”,因为您已经从“if”中的方法返回。
如果用户可以使用您的 WebView 访问任何网站,并且您对其他网站出于其目的应用相同的键/值对感到偏执,那么您可以轻松添加另一个检查来确定该 url 是否位于“您的”域中。
If you have control over the server side content, then definitely go with the suggestion Theo made. Since you indicate the pages should also load in standard browers, don't use a custom scheme, but make
rel=external
part of the actual url you're linking/redirecting to.By doing that, you can easily parse the
url
parameter inshouldOverrideUrlLoading(WebView view, String url)
and check for above key/value pair. I would suggest you parse it into aUri
and usegetQueryParameter(key)
to check for the value matchingrel
. If it'sexternal
, fire off an Intent.It would look something like this:
On a side note: no need to declare an 'else' since you already return from the method in the 'if'.
If users can go to any site using your WebView and if you're paranoid about other sites applying the same key/value pair for their purposes, you could easily add another check to determine whether the url is on 'your' domain.