【发布时间】:2014-08-24 04:59:42
【问题描述】:
我想在自定义 webview 客户端(没有 JavaScript 注入)中实现一种可以阻止广告的机制。是否有一种方法可以捕捉广告并将其替换为来自受信任来源的其他广告? 谢谢
【问题讨论】:
标签: android browser webview ads
我想在自定义 webview 客户端(没有 JavaScript 注入)中实现一种可以阻止广告的机制。是否有一种方法可以捕捉广告并将其替换为来自受信任来源的其他广告? 谢谢
【问题讨论】:
标签: android browser webview ads
在您的自定义WebViewClient 中,您可以覆盖函数shouldInterceptRequest(WebView, WebResourceRequest)。
来自安卓docs:
将资源请求通知宿主应用程序并允许应用程序返回数据。
所以一般的想法是检查请求是否来自广告 URL(那里有很多黑名单过滤器),然后返回不是广告的“假”资源。
如需更深入的解释和示例,我建议查看blog post。
【讨论】:
我做了一个自定义的WebViewClient 喜欢:
public class MyWebViewClient extends WebViewClient {
@Override
public void onPageFinished(WebView view, String url) { }
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.endsWith(".mp4")) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(url), "video/*");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
view.getContext().startActivity(intent);
return true;
} else if (url.startsWith("tel:") || url.startsWith("sms:") || url.startsWith("smsto:")
|| url.startsWith("mms:") || url.startsWith("mmsto:")) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
view.getContext().startActivity(intent);
return true;
} else {
return super.shouldOverrideUrlLoading(view, url);
}
}
private Map<String, Boolean> loadedUrls = new HashMap<>();
@SuppressWarnings("deprecation")
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
boolean ad;
if (!loadedUrls.containsKey(url)) {
ad = AdBlocker.isAd(url);
loadedUrls.put(url, ad);
} else {
ad = loadedUrls.get(url);
}
return ad ? AdBlocker.createEmptyResource() :
super.shouldInterceptRequest(view, url);
}
}
并创建了一个 AdBlocker 类,例如:
public class AdBlocker {
private static final Set<String> AD_HOSTS = new HashSet<>();
public static boolean isAd(String url) {
try {
return isAdHost(getHost(url));
} catch (MalformedURLException e) {
Log.e("Devangi..", e.toString());
return false;
}
}
private static boolean isAdHost(String host) {
if (TextUtils.isEmpty(host)) {
return false;
}
int index = host.indexOf(".");
return index >= 0 && (AD_HOSTS.contains(host) ||
index + 1 < host.length() && isAdHost(host.substring(index + 1)));
}
public static WebResourceResponse createEmptyResource() {
return new WebResourceResponse("text/plain", "utf-8", new ByteArrayInputStream("".getBytes()));
}
public static String getHost(String url) throws MalformedURLException {
return new URL(url).getHost();
}
}
并在您的oncreate 中使用此WebViewClient,例如:
webview.setWebViewClient(new MyWebViewClient());
【讨论】:
要实现这一点,您有两种选择:
【讨论】: