webview中的Android屏蔽广告

问题描述 投票:4回答:3

我想在自定义webview客户端(没有JavaScript注入)中实现一个可以阻止广告的机制。我是否可以通过受信任的来源抓取广告并将其替换为其他广告?谢谢

android browser webview ads
3个回答
4
投票

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

来自Android docs

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

因此,一般的想法是检查请求是否来自广告网址(大量黑名单过滤器),然后返回不是广告的“假”资源。

有关更深入的解释和示例,我建议您查看此blog post


1
投票

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

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

0
投票

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

}

并在你的WebViewClient中使用这个oncreate像:

 webview.setWebViewClient(new MyWebViewClient());
© www.soinside.com 2019 - 2024. All rights reserved.