5

I am about to roll out WebView AdBlocking in my android app. I want to know if this will effectively block ads or if there is more to be done say within the Webview itself which I have not modified. Basically I have a host file of stored in Android assets which lists hundred of ad server sites. I read this file in to my AdBlocker and then apply it inside the WebViewClient as follows:

// AdBlocker.isAdURL(String url)

 public Boolean isAdURL(String url){
      Boolean retValue = false;
      if ((url == null) || (url.isEmpty()))
        return false;
      if ((adServers == null)|| (adServers.size() <1))
        return false;
      try{
        String domainName = getUrlsDomain(url);
        if (adServers.contains(domainName)) {
            retValue = true;
        }
    } catch(URISyntaxException e){

    }

    return retValue;
}

And I only use this in WebViewClient as follows:

@Deprecated
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {

      if (adBlocker.isAdURL(url)) {
         ByteArrayInputStream nada = new ByteArrayInputStream("".getBytes());
        return new WebResourceResponse("text/plain", "utf-8", nada);
     }
    return super.shouldInterceptRequest(view, url);
}

And similarly:

 @Override
 public WebResourceResponse shouldInterceptRequest(WebView view,  WebResourceRequest request) {
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        if (adBlocker.isAdURL(request.getUrl().toString())) {
            ByteArrayInputStream nada = new    ByteArrayInputStream("".getBytes());
            return new WebResourceResponse("text/plain", "utf-8", nada);
        }

    }

    return super.shouldInterceptRequest(view, request);
}

Anything more need to be done? Or is that it? Any need to keep a whitelist or will this generally work assuming my list of adservers is current?

  • _could you post your getUrlsDomain(url) function?_ --> never mind, found answer here: [link](http://stackoverflow.com/questions/9607903/get-domain-name-from-given-url#9608008) – xtools Mar 29 '16 at 07:30
  • Hope this like helps you. It works perfectly for me : https://stackoverflow.com/a/52341184/8197867 – Devangi Sep 15 '18 at 02:57

2 Answers2

3

This implementation is basically the same as the "whitelist" feature in Cordova. They also use shouldInterceptRequest for blocking requests to non-whitelisted sites. There known shorthands of this approach, e.g. it doesn't catch requests done via WebSockets protocol (see this book excerpt), but in general it's a recommended approach (look for shouldInterceptRequest in that document).

In order to do better, you will need to do all the content loading yourself (using some HTTP client), filter out and sanitize the content, and then pass the results to WebView in order to render. This is how GMail Android app works for example (they do actual sanitization on the server, but it's also possible to do it on the device).

Mikhail Naganov
  • 6,643
  • 1
  • 26
  • 26
  • Ok, I have looked at Jericho html parser for some cleaning capabilities. Perhaps that or JSoup could be used .... – FunctionallyReactive Mar 02 '16 at 12:57
  • Are there other good open source libraries for this type of parsing? I am also looking at implementing a reader mode which would be would of course not allow ads – FunctionallyReactive Mar 02 '16 at 13:01
  • Yes, JSoup seems like a good solution for Java. But this is a complex question deserving an article on its own. E.g. do you want to allow content to be generated dynamically by JavaScript? I would say that `shouldInterceptRequest` will work in 90% of cases, and solving the remaining 10% is really hard. – Mikhail Naganov Mar 02 '16 at 19:50
3

If anyone is looking for a simpler way to do this, the AdBlock plus Github page offers an AdblockWebView. To use it, you add this line to your Gradle file:

implementation 'org.adblockplus:adblock-android-webview:3.0'

And then add this to your layout's XML file:

<org.adblockplus.libadblockplus.android.webview.AdblockWebView
    android:id="@+id/main_webview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
Community
  • 1
  • 1
Code on the Rocks
  • 11,488
  • 3
  • 53
  • 61