0

我有一个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 域的解决方案,因为有任意数量的域需要被视为内部域并且我无法提前知道或在运行中轻松确定。)

4

3 回答 3

2

如果您不想修改现有 URL,我认为您的原始建议的变体可能是最好的。

用于addJavaScriptInterface添加一个类来处理您的外部 URL 加载。内部类可能如下所示:

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. 您可以通过创建自定义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,或者您可以使用 loadUrl 在加载 JavaScript 之前先手动加载 JQuery。

请注意,这种方法完全放弃了任何使用shouldOverrideUrlLoading

于 2012-01-20T02:50:19.260 回答
1

我的建议是使用另一种指定外部 URL 的方式……将这些信息嵌入到 URL 中,因此与该shouldOverrideUrlLoading功能兼容。具体来说,创建自定义方案 URL 并将真实页面作为参数传递:

myappname://external?url=encoded_real_page_url

然后在shouldOverrideUrlLoading函数中检查它是否是自定义方案 URL,提取 url 参数,对其进行解码然后重定向。

于 2012-01-08T20:54:32.573 回答
1

如果您可以控制服务器端的内容,那么一定要听从 Theo 提出的建议。由于您指示页面也应该在标准浏览器中加载,因此不要使用自定义方案,而是将rel=external您链接/重定向到的实际 url 作为一部分。

通过这样做,您可以轻松地解析url参数shouldOverrideUrlLoading(WebView view, String url)并检查上述键/值对。我建议您将其解析为 aUri并用于getQueryParameter(key)检查值是否匹配rel。如果是external,则触发 Intent。

它看起来像这样:

@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 访问任何站点,并且如果您对其他站点应用相同的键/值对为他们的目的感到偏执,您可以轻松地添加另一个检查以确定 url 是否在“您的”域上。

于 2012-01-14T11:31:30.500 回答