Android 第三方應用廣告攔截實現

前段時間,公司製造的機器裏應用裝有不良廣告,嚴重影響了兒童客戶使用者的思想健康,導致被人投訴。於是乎,就有了想研發一款類似於360廣告屏蔽的應用的念頭。嗯,事情就是這樣,現在切入主題。

目前市場上有很多安全軟件,它們攔截第三方應用廣告的方式都不一樣,比如說有 以so 注入方式來攔截彈出廣告。 
現在我們來看下這種方式的詳細情況:

要做到攔截,首先我們得知道廣告是怎麼出來的,原來第三方應用大部分是以加入廣告jar形式加入廣告插件,然後在AndroidManifest中聲明廣告service或者在程序中執行廣告Api,廣告插件再通過Http請求去加載廣告。在java中,有四種訪問網絡的接口,如apache的http庫(如下介紹),這幾種方式首先都會通過getaddrinfo函數獲取域名地址,然後通過connect函數連接到服務器讀取廣告信息。

  1. WebView(源碼文件在frameworks/base/core/java/android/webkit/WebView.java)。通過WebView類的void loadUrl(String url)、void postUrl(String url, byte[] postData)、void loadData(String data, String mimeType, String encoding)、void loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl)、void evaluateJavascript(String script, ValueCallback resultCallback)等加載網頁。
  2. apache-http(源碼目錄在external/apache-http/ , HttpGet 和 HttpPost類)。通過external/apache-http/src/org/apache/http/impl/client/DefaultRequestDirector.java中的DefaultRequestDirector類的HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context)方法執行訪問的網絡的動作。
  3. okhttp(源碼目錄在external/okhttp/)。通過external/okhttp/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java中的HttpEngine類的private void connect(Request request) throws IOException方法連接網絡。
  4. URL(源碼在libcore/luni/src/main/java/java/net/URL.java)。通過libcore/luni/src/main/java/java/net/URL.java中的URL類的URLConnection openConnection() throws IOException方法和URLConnection openConnection(Proxy proxy) throws IOException方法連接網絡。

然後再來說說動態庫注入,具體什麼是動態庫注入,以及如何注入,網上有很多文章,這裏就不介紹。動態庫注入攔截呢,主要是攔截getaddrinfo,根據條件返回錯誤來攔截網絡請求,達到攔截作用。不過需要注意一點就是攔截之前要確定你所攔截的動態庫是否是你需要攔截的庫?例如A程序調用了動態庫BO和CO,而BO和CO都調用了connect函數,此時需要攔截BO的請求,需要注入到BO動態庫並修改GOT表,而不是注入到CO中。

攔截HTTP方式廣告在多數廣告包中,應用程序首先會通過apache的http庫或JDK中的http方法先將廣告數據下載過來,然後通過WebView顯示。這種方式通過注入攔截進程的/system/lib/libjavacore.so可實現廣告地址攔截。

攔截WebView方式廣告廣告插件也可以直接通過WebView加載URL,通過分析WebView加載流程可知它的網絡處理過程均交給libchromium_net庫來完成。因此通過注入libjavacore.so是無法實現攔截,而是需要注入到/system/lib/libchromium_net.so。

通過這種方式已經完全能夠攔截掉第三方APP廣告,但存在一些問題:

1.廣告商可以通過JNI方式調用系統getaddrinfo與connect實現自己的解析與連接過程的動態庫,從而跳過libjavacore.so導致攔截無效。 
2.攔截WebView方式廣告雖然能夠不顯示廣告,但通常仍然會有浮動框顯示”網頁無法打開”,從而影響美觀。 
3.最重要的是我們機器是沒有root權限的!!

第三個問題直接導致了放棄了這種注入做法。 
來來去去一段時間後,目前是採用android 系統本地掃描第三方應用廣告形式。具體怎麼做,請往下看!

所以具體廣告插件掃描方案是匹配包名+類名形式的: 
1.掃描本地所有第三方應用,列出一個應用中的所有類,將包名+類名方式與廣告插件特徵庫進行匹配; 
2.將匹配出來的應用所帶廣告特徵,通過系統提供傳入接口,將這些規則設置進去。(當然,系統代碼是需要改的,做了一些處理,主要是在上面介紹中的幾種訪問網絡方式上做了判斷處理)

這種方案的關鍵在於廣告特徵庫的完善,廣告插件特徵庫收集越全,掃描出來的廣告插件就可以越準確。所幸,公司有幾位大神,做過類似的事情,所以工作簡單了多些。

獲取第三方應用:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">   <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** 
     * 查詢機器內非本公司應用 
     */</span>  
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> List<PackageInfo> <span class="hljs-title" style="box-sizing: border-box;">getAllLocalInstalledApps</span>() {  
        List<PackageInfo> apps = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ArrayList<PackageInfo>();  
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(pManager == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>){
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> apps;
        }
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//獲取所有應用  </span>
        List<PackageInfo> paklist = pManager.getInstalledPackages(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);  
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < paklist.size(); i++) {  
            PackageInfo pak = (PackageInfo) paklist.get(i);

           <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//屏蔽掉公司內部應用</span>
           <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//...</span>

           <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//判斷是否爲非系統預裝的應用程序  </span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ((pak.applicationInfo.flags & pak.applicationInfo.FLAG_SYSTEM) <= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {  
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// customs applications </span>
                apps.add(pak);
            }  
        }  
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> apps;  
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li></ul>

獲取某個應用的廣告特徵:

<code class="hljs javascript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">public static List<<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>> getClassNameByDex(Context context,
            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span> packageName) {

        List<<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>> datalist = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ArrayList<<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>>();
        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span> path = <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">null</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
            path = context.getPackageManager().getApplicationInfo(packageName,
                    <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>).sourceDir;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 獲得某個程序的APK路徑</span>
        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (NameNotFoundException e) {
            e.printStackTrace();
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(TextUtils.isEmpty(path)){
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> datalist;
            }
            DexFile dexFile = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> DexFile(path);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// get dex file of APK</span>
            Enumeration<<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>> entries = dexFile.entries();
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (entries.hasMoreElements()) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// travel all classes</span>
                <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span> className = (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>) entries.nextElement();
                <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span> totalname = packageName + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"."</span>+className;
                datalist.add(totalname);
            }

        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (IOException e) {
            e.printStackTrace();
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> datalist;
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li></ul>

將應用中的所有類名與特徵庫進行匹配:

<code class="hljs javascript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (PackageInfo info : infolsit) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (info == <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">null</span>) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">continue</span>;
        }
        data = getClassNameByDex(context,info.packageName);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(data == <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">null</span>){
            Log.d(TAG,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"getAdFlagForLocalApp()  類名解析出錯"</span>+info.packageName);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">continue</span>;
        }
        sgPgmap = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> HashMap<<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>>();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span> clsname : data) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (ADSInfo adinfo : flaglist) {
                <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span> flag = adinfo.getAdFlag();  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//廣告樣本庫的某一標識 </span>
                <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span> adpg = adinfo.getAdName();  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//廣告樣本庫的某一包名</span>
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (clsname.contains(adpg)) {  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//匹配類名與廣告特徵庫裏的匹配符,看是否包含關係</span>
                    sgPgmap.put(flag,info.packageName);
                }
            }
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(sgPgmap.size() > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>){
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//AdsPgInfo  一個對應應用裏包含了多少個標識</span>
            adspginfo = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> AdsPgInfo(info.packageName, sgPgmap);
            pglist.add(adspginfo);
        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>

ps: 在匹配時,有一個很注意的點,有時候單單類名匹配不準,或者會漏掉某些廣告,所以應該加上包名,再去匹配特徵庫裏的匹配符,這樣才能百無一漏。

在此舉例一個指智廣告的特徵(特徵顯示形式可自定義,只要符合自己的解析策略即可):

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">ads<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.banner</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.zhidian</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#指智廣告#com/adzhidian/#ad.zhidian3g.cn</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
  • ads.banner.zhidian 爲該類型廣告標識,主要是爲了匹配時應用對應標識的簡潔性,不用直接跟着一羣特徵到處跑。。
  • 指智廣告 該廣告名稱
  • com/adzhidian/ 該廣告用來匹配應用中類名的匹配符,當應用中某一(包名+類名)包含該匹配符時,說明了該應用包含該廣告
  • ad.zhidian3g.cn 需要傳給系統的一個規則特徵。

匹配出所有應用的所屬規則特徵後,接下來需要傳給系統了,系統將滿足需求的幾個接口提供出來。這邊涉及到修改系統層代碼,我就主要講下實現思路,會貼出關鍵的幾個代碼。 
實現思路:系統根據應用層傳入的應用包名以及規則,將其緩存,在webview或http處請求時,對其進行判斷處理。

添加某應用規則接口:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
 * add Adblock url of package pkgName
 */</span>
 <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">addAdblockUrlInner</span>(String pkgName, String url) {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">synchronized</span> (mAdblockEntries) {
      HashMap<String, UrlEntry> pkgEntry = mAdblockEntries.get(pkgName);
     <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (pkgEntry == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
        pkgEntry = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> HashMap<String, UrlEntry>();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (pkgEntry == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
            Slog.e(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"addAdblockUrl():new HashMap<String, UrlEntry>() fail!"</span>);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
        }
        mAdblockEntries.put(pkgName, pkgEntry);
     }
     UrlEntry entry = pkgEntry.get(url);
     <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (entry == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
        pkgEntry.put(url, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> UrlEntry(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>));
      } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
        entry.deleted = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
      }
   }
   <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li></ul>

WebView類postUrl處判斷處理:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
 * Loads the given URL.
 *
 *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> url the URL of the resource to load
 */</span>
   <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">loadUrl</span>(String url) {
        checkThread();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!isAddressable(url)) {
           <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;
        }
       <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (DebugFlags.TRACE_API) Log.d(LOGTAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"loadUrl="</span> + url);
       <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(!isChromium && url.startsWith(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"file://"</span>)){
       Log.e(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"WebView.java"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"loadurl setLocalSWFMode"</span>);
       mProvider.setLocalSWFMode();
   }

 <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
  * Returns true if the url is not included by adblock service
  */</span>
 <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">isAddressable</span>(String url) {
     <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> addressable = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
     AdblockManager adblockManager = AdblockManager.getInstance();
     <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (adblockManager != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
       String adblockUrl =  adblockManager.containedAdblockUrl(ActivityThread.currentPackageName(), url);
     <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (adblockUrl != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
         addressable = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
         adblockManager.increaseNumberOfTimes(ActivityThread.currentPackageName(), adblockUrl);
      }
      }
      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> addressable;
  }
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li></ul>

由於系統代碼這部分的改動並非是我改的,更深細節處的理論就不清楚了。 
應用層的廣告特徵庫爲了可以持續更新,建議可以做成網絡更新方式。 
據此,廣告攔截功能實現就完成了,可能會有瑕疵,不過持續優化中。 有大神如果有更好的攔截實現跟策略,請您麻煩私信我,讓我好好請教,非常感謝。

轉載自:http://blog.csdn.net/u012583459/article/details/47394555

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章