如何跳過掘金app的開屏廣告(二)

語言: CN / TW / HK

這是我參與8月更文挑戰的第24天,活動詳情檢視:8月更文挑戰

如何跳過掘金app的開屏廣告(二)

上篇文章分析了,想要獲取跳過開屏廣告的核心就是手機幫助我們點選跳過按鈕,最終也選定了無障礙服務作為我們的技術,這篇文章將實現跳過廣告功能程式碼。

一、效果

程式點選跳過要比手動點選快得多。

1629623520219210.gif

二、程式碼實現

2.1 關鍵回撥

建立的服務繼承AccessibilityService類之後,又一個關鍵的回撥,是onAccessibilityEvent回撥,我們的邏輯都在這個方法中。

@Override public void onAccessibilityEvent(AccessibilityEvent event) { }

2.1 定位包名

我們只想在某個app或者某些app下進行跳過廣告。

兩種方法

  1. 在xml的config檔案的 android:packageNames 屬性新增應用包名
  2. 在service中獲取包名,進行判斷。

``` String packageStr = event.getPackageName().toString();

if (TextUtils.equals(packageStr, "com.xx.xxx")) {

} ```

比如獲取到的掘金app的包名是 com.daimajia.gold

ps: 隨手網上搜索了一下程式碼家,github上顯示這個人是掘金的CTO了。

2.2 定位目標元件

想給一個元件新增點選方法,首先要定位到這個元件,獲取這個元件,然後才能新增點選動作。

怎麼定位元件呢?

筆者這裡常用的有三種方法。

  1. uiautomator, Android sdk中自帶,可以很方便的使用
  2. autoJs,這是一款app,也是用無障礙服務,基於無障礙服務添加了圖形化介面,在手機端方便檢視。
  3. 自己使用程式碼遍歷檢視。

具體分析:

掘金app的右上角有“跳過”文字,分析檢視結構,大概是這樣。

虛擬碼

``` // 實際點選事件在這個

// 這個是跳過效果的進度

// 跳過的文字載體

```

2.3 獲取目標元件

首先獲取到當前頁面的所有元件 -> 然後獲取到目標元件

使用getRootInActiveWindow() 獲取所有的元件
使用findAccessibilityNodeInfosByViewId(“”)獲取所有符合該ID的NodeList 使用findAccessibilityNodeInfosByText() 獲取所有符合該文字的NodeList

``` AccessibilityNodeInfo sourceNodeInfo = getRootInActiveWindow(); if (sourceNodeInfo == null) return;

        List<AccessibilityNodeInfo> textNodeInfoList = sourceNodeInfo.findAccessibilityNodeInfosByViewId("com.daimajia.gold:id/fl_skip");
        if (textNodeInfoList.size() > 0) {
            textNodeInfoList.get(0).performAction(AccessibilityNodeInfo.ACTION_CLICK);
        }

```

2.4 設定點選操作

找到目標的定位的AccessibilityNodeInfo之後,我們開始進行操作。

常用的有

ACTION_CLICK:在節點資訊上點選的操作。 ACTION_LONG_CLICK:在節點上點選長按的操作。 ACTION_COPY:將當前選擇拷貝到剪貼簿的操作。 ACTION_CUT:剪貼當前選項並放置到剪貼簿的操作。 ACTION_FOCUS:給節點新增輸入焦點的操作。

我們執行 AccessibilityNodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK); 就可以達到效果了。

2.5 程式碼部分

想要實現其它app的功能,可以在程式碼上進行拓展。

完整程式碼。

``` package com.demo.accessibilitydemo;

import android.accessibilityservice.AccessibilityService; import android.text.TextUtils; import android.util.Log; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo;

import java.util.List;

public class MyService extends AccessibilityService {

private final String TAG = "MyService";

public MyService() {
}

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {

    Log.d(TAG, "package:" + event.getPackageName());

    String packageStr = event.getPackageName().toString();

    if (TextUtils.equals(packageStr, "com.daimajia.gold")) {
        AccessibilityNodeInfo sourceNodeInfo = getRootInActiveWindow();
        if (sourceNodeInfo == null)
            return;

        List<AccessibilityNodeInfo> textNodeInfoList = sourceNodeInfo.findAccessibilityNodeInfosByViewId("com.daimajia.gold:id/fl_skip");
        if (textNodeInfoList.size() > 0) {
            textNodeInfoList.get(0).performAction(AccessibilityNodeInfo.ACTION_CLICK);
        }

    }

}

@Override
public void onInterrupt() {

}

}

```