[JAVA] [Android] Implement Adblock in WebView

I want to remove WebView ads

If you turn off javascript, most ads will disappear, but if you can't use javascript, it's inconvenient, so it's a memo when you implement adblock. In English, the materials were suitable, but I couldn't find the Japanese page.

reference

You can implement it by following this page https://www.hidroh.com/2016/05/19/hacking-up-ad-blocker-android/

Ad host list https://sites.google.com/site/hosts2ch/

General flow

Override WebViewClient.shouldInterceptRequest () to determine if the request URL from within the page is the ad serving host. If it's an ad, it returns an empty response. that's all.

Implementation

Shape the ad host list to make it easier to handle

You can download a list of hosts serving ads at https://sites.google.com/site/hosts2ch/. (Very convenient .. !!) I think that it will look like this when downloaded, so I will mold it so that it is easy to handle.

ja.txt


# hosts2ch - Japanese mobile ad servers hosts file.
# This file is public domain, of course.
#
# file size: 34 kB
# entries: 1279
#
# ---------- last updated: 2019-01-16  ---------- 


127.0.0.1 100234.advision-adnw.jp
127.0.0.1 100291.adnico.jp
127.0.0.1 100602.advision-adnw.jp
127.0.0.1 100651.advision-adnw.jp
127.0.0.1 100800.advision-adnw.jp
127.0.0.1 101623.sprout-ad.com
127.0.0.1 107008.speead.jp
127.0.0.1 150601.fc2rs.com
127.0.0.1 1tmg.info
127.0.0.1 2.chmato.me
・
・
・

Remove the comment line and IP address column of this to make it hosts only and name the file hosts.txt. Like this ↓

hosts.txt


100234.advision-adnw.jp
100291.adnico.jp
100602.advision-adnw.jp
100651.advision-adnw.jp
100800.advision-adnw.jp
101623.sprout-ad.com
107008.speead.jp
150601.fc2rs.com
1tmg.info
2.chmato.me
・
・
・

Add hosts.txt to your project file

Add it to the assets folder. If you don't have an assets folder, create one.

スクリーンショット 2019-01-22 15.57.10.png

Implement AdBlock

AdBlocker.java


public class AdBlocker {
    private static final String AD_HOSTS_FILE = "hosts.txt";
    private static final Set<String> AD_HOSTS = new HashSet<>();

    public static void init(final Context context) {
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                try {
                    loadFromAssets(context);
                } catch (IOException e) {
                    // noop
                }
                return null;
            }
        }.execute();
    }

    @WorkerThread
    private static void loadFromAssets(Context context) throws IOException {
        InputStream stream = context.getAssets().open(AD_HOSTS_FILE);
        BufferedSource buffer = Okio.buffer(Okio.source(stream));
        String line;
        while ((line = buffer.readUtf8Line()) != null) {
            AD_HOSTS.add(line);
        }
        buffer.close();
        stream.close();
    }

    public static boolean isAd(String url) {
        HttpUrl httpUrl = HttpUrl.parse(url);
        return isAdHost(httpUrl != null ? httpUrl.host() : "");
    }

    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)));
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public static WebResourceResponse createEmptyResource() {
        return new WebResourceResponse("text/plain", "utf-8", new ByteArrayInputStream("".getBytes()));
    }
}

Implement WebViewClient.shouldInterceptRequest ()

Override and implement the WebViewClient's shouldInterceptRequest () method. All requests from the source read by webview pass through shouldInterceptRequest () once (I understand that it is correct)

MyWebViewClient.java


private Map<String, Boolean> loadedUrls = new HashMap<>();

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@override99 
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
        boolean ad;
        if (!loadedUrls.containsKey(url)) {
            ad = AdBlocker.isAd(url);
            loadedUrls.put(url, ad);
        } else {
            ad = mLoadedUrls.get(url);
        }
        return ad ? AdBlocker.createEmptyResource() :
                super.shouldInterceptRequest(view, url);
    }

Implement Application

Initialize AdBlocker in MyApplication that inherits Application.

MyApplication.java


public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        AdBlocker.init(this);
    }
}

Don't forget to add it to Android Manifest.

AndroidManifest.xml


<application
        android:name="MyApplication"
        ....
        ....
/>

that's all

https://www.hidroh.com/2016/05/19/hacking-up-ad-blocker-android/ Almost as shown on this page, so please refer to here for details.

Recommended Posts

[Android] Implement Adblock in WebView
Implement CustomView in code
Notes in Android studio
Implement markdown in Rails
Implement application function in Rails
[Beginner] Implement NavigationBar in code
Implement follow function in Rails
Implement Firebase Cloud Messaging in your Android app (2)-Receive messages in your app
Implement two-step verification in Java
Implement LTI authentication in Rails
Implement Basic authentication in Java
Implement math combinations in Java
2 Implement simple parsing in Java
Implement Email Sending in Java
Implement Swift UITextField in code
Implement import process in Rails
How to implement one-line display of TextView in Android development
Implement functional quicksort in Java
Implement rm -rf in Java.
Implement XML signature in Java
Implement Table Driven Test in Java 14
Implement textField focus-out event in JavaFX
Try implementing Android Hilt in Java
How to hide scrollbars in WebView
3 Implement a simple interpreter in Java
Try to implement Yubaba in Ruby
Implement simple login function in Rails
Implement tagging function in form object
Implement Material Design View in Kotlin
Automatically insert `@SuppressWarnings` in Android Studio
OkHttp3 (GET, POST) in Android Studio
Implement a gRPC client in Ruby
Implement REST API in Spring Boot
Implement a contact form in Rails
Implement Spring Boot application in Gradle
Try to implement Yubaba in Java
Implement CSV download function in Rails
1 Implement simple lexical analysis in Java
Implement ripple representation on images on Android