Android WebView ceding rel=活动管理器的外部链接
我有一个Android WebView ceding rel=活动管理器的外部链接,android,webview,android-webview,rel,webviewclient,Android,Webview,Android Webview,Rel,Webviewclient,我有一个WebView,其中我希望在Android浏览器中打开带有rel=external的锚定标签,但所有其他链接保留在WebView中 因此,如果用户点击标记如下所示的链接,内容将加载到WebView: <a href="http://example.com/">Whatever</a> <a href="http://example.com/" rel="external">Whatever</a> @Override public bo
WebView
,其中我希望在Android浏览器中打开带有rel=external
的锚定标签,但所有其他链接保留在WebView
中
因此,如果用户点击标记如下所示的链接,内容将加载到WebView
:
<a href="http://example.com/">Whatever</a>
<a href="http://example.com/" rel="external">Whatever</a>
@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;
}
public class JavaScriptInterface {
public void viewExternalUrl(String url) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);
return true;
}
}
确定是否存在rel=external
属性/值的最佳方法是以某种方式使用addJavascriptInterface()
,并让JavaScript通知Java是否存在rel
属性以及值是什么
还是有更好的办法
(我正在寻找一种不涉及检查URL域的解决方案,因为有任意数量的域需要被视为内部域,我无法提前知道或快速确定。)我的建议是使用不同的方式指定外部URL。。。将该信息嵌入URL并因此与
shouldOverrideUrlLoading
函数兼容的URL。具体而言,创建自定义方案URL并将真实页面作为参数传递:
myappname://external?url=encoded_real_page_url
然后在
shouldOverrideUrlLoading
函数中检查它是否是自定义方案URL,提取URL参数,解码它,然后重定向。我的建议是使用不同的方式指定外部URL。。。将该信息嵌入URL并因此与shouldOverrideUrlLoading
函数兼容的URL。具体而言,创建自定义方案URL并将真实页面作为参数传递:
myappname://external?url=encoded_real_page_url
然后在
shouldOverrideUrlLoading
函数中检查它是否是自定义方案URL,提取URL参数,解码它,然后重定向。如果您可以控制服务器端内容,那么一定要按照Theo提出的建议去做。由于您指示页面也应在标准浏览器中加载,因此不要使用自定义方案,而是使rel=external
成为您链接/重定向到的实际url的一部分
通过这样做,您可以轻松解析shouldOverrideUrlLoading(WebView视图,字符串url)
中的url
参数,并检查上述键/值对。我建议您将其解析为,并使用检查值是否匹配rel
。如果是外部的
,则触发一个意图
它看起来像这样:
<a href="http://example.com/">Whatever</a>
<a href="http://example.com/" rel="external">Whatever</a>
@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;
}
public class JavaScriptInterface {
public void viewExternalUrl(String url) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);
return true;
}
}
另请注意:无需声明'else',因为您已经从'if'中的方法返回
如果用户可以使用您的WebView访问任何站点,如果您对其他站点应用相同的密钥/值对的目的心存疑虑,您可以轻松地添加另一项检查,以确定url是否位于“您的”域中。如果您可以控制服务器端内容,那么一定要采纳Theo提出的建议。由于您指示页面也应在标准浏览器中加载,因此不要使用自定义方案,而是使
rel=external
成为您链接/重定向到的实际url的一部分
通过这样做,您可以轻松解析shouldOverrideUrlLoading(WebView视图,字符串url)
中的url
参数,并检查上述键/值对。我建议您将其解析为,并使用检查值是否匹配rel
。如果是外部的
,则触发一个意图
它看起来像这样:
<a href="http://example.com/">Whatever</a>
<a href="http://example.com/" rel="external">Whatever</a>
@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;
}
public class JavaScriptInterface {
public void viewExternalUrl(String url) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);
return true;
}
}
另请注意:无需声明'else',因为您已经从'if'中的方法返回
如果用户可以使用您的WebView访问任何站点,并且您对其他站点应用相同的密钥/值对的目的心存疑虑,那么您可以轻松添加另一项检查,以确定url是否位于“您的”域中。如果您不想修改现有url,我认为您的原始建议的变体可能是最好的 使用
addJavaScriptInterface
添加一个类来处理外部URL加载。内部类可能如下所示:
<a href="http://example.com/">Whatever</a>
<a href="http://example.com/" rel="external">Whatever</a>
@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;
}
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)。您可以通过创建自定义和重写来检测页面加载完成
我还没有测试过这些代码,但它应该可以工作,假设您在页面中加载了JQuery。如果没有,您可能会想出一些JavaScript来操作DOM而不使用它,或者您可以在加载JavaScript之前先使用loadUrl手动加载JQuery
请注意,这种方法完全放弃了任何使用
shouldOverrideUrlLoading
的方法。如果您不想修改现有的URL,我认为您的原始建议的变体可能是最好的
使用addJavaScriptInterface
添加一个类来处理外部URL加载。内部类可能如下所示:
<a href="http://example.com/">Whatever</a>
<a href="http://example.com/" rel="external">Whatever</a>
@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;
}
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)。您可以通过创建自定义和重写来检测页面加载完成
我还没有测试过这些代码,但它应该可以工作,假设您在页面中加载了JQuery。如果没有,您可能会想出一些JavaScript来操作DOM而不使用它,或者您可以在加载JavaScript之前先使用loadUrl手动加载JQuery
请注意,这种方法完全放弃了使用
shouldOverrideUrlLoading
我在WebView中查看的页面也需要通过标准浏览器查看,因此如果我这样做,我需要解决这个问题。也许我可以让我的应用程序在加载页面时将JavaScript注入每个页面,然后用自定义方案重写URL。如果没有,那么也许我可以尝试处理