Android 在 webview 中屏蔽广告

Posted

技术标签:

【中文标题】Android 在 webview 中屏蔽广告【英文标题】:Android block ads in webview 【发布时间】:2014-08-24 04:59:42 【问题描述】:

我想在自定义 webview 客户端(没有 javascript 注入)中实现一种可以阻止广告的机制。是否有一种方法可以捕捉广告并将其替换为来自受信任来源的其他广告? 谢谢

【问题讨论】:

【参考方案1】:

在您的自定义WebViewClient 中,您可以覆盖函数shouldInterceptRequest(WebView, WebResourceRequest)

来自安卓docs:

将资源请求通知宿主应用程序并允许应用程序返回数据。

所以一般的想法是检查请求是否来自广告 URL(那里有很多黑名单过滤器),然后返回不是广告的“假”资源。

如需更深入的解释和示例,我建议查看blog post。

【讨论】:

这是正确答案。链接的博客文章包含示例代码的详细说明。【参考方案2】:

我做了一个自定义的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());

【讨论】:

如何启用和禁用广告拦截器【参考方案3】:

要实现这一点,您有两种选择:

    使用 Javascript 注入代码来执行此操作(您明确表示不希望这样做) 在 WebView 中,而不是“http://example.com”加载“http://myproxy.com?t=http://example.com”(当然,正确转义)并将“myproxy.com”设置为将获取上游页面的代理(在“t”查询中给出参数,或以任何其他方式)并在向客户端发送响应之前将广告替换为受信任的广告。不过,这将非常复杂,因为广告可以有多种形式,它们通常是自己注入的 Javascript,您可能需要在获取的 html、CSS 和 JS 文件等中重写很多 URL。

【讨论】:

如果发生 Javascript 注入,您能否提供一个示例,或者如果您有一个可以帮助我的链接,那就太好了。 恐怕用 JS 的方式来做也不容易。您可以在此处获取 AdBlock 源代码:adblockplus.org/en/source,您需要对其进行一些修改。我不知道有任何其他此类优秀的开源项目。 你能帮我提供更多关于你的第二个答案的细节吗..一些代码步骤可能..从上次我一直在努力解决各种提示但没有任何效果(或者它只对一些有用) api版本) @kamituel...我找到了如何配置本地代理 ***.com/questions/4488338/webview-android-proxy 但我不明白如何从该本地代理加载 url

以上是关于Android 在 webview 中屏蔽广告的主要内容,如果未能解决你的问题,请参考以下文章

android中,如何屏蔽WebView里的超链接?

android源码中在framework层如何修改代码屏蔽掉home按键

广告商哭了:iOS 9 Safari 或屏蔽广告

求助ANDROID APP逆向:如何屏蔽showConfirmDialog确认框?

Android 应用安全 - WebView请求过滤

iOS支持Safari广告屏蔽 移动广告行业并不怕