Android:輔助功能之自動搶紅包

hi大家好。
新年又來了,微信群里又是各種紅包橫飛。作為技術人員的我們卻大可不必擔心一不小心,手速慢了點,又錯過了幾十萬。我們可以通過安卓的輔助功能來實現自己的微信自動搶紅包,安全又快捷。

輔助服務

我們在 設置->無障礙 中,就可以看到手機中所有的輔助服務了。輔助功能通常是針對一些視力聽力等有障礙導致使用手機有障礙的人群,做一些語言提醒等幫助他們更好地使用手機。
因為輔助功能可以得到系統級別的事件和服務,第三方應用的輔助功能都需要手動開啟。我們常用的綠色守護,冰箱等應用都是利用輔助服務實現的。

image

我們先來實現一個簡單的輔助服務吧。

1,繼承AccessibilityService類。AccessibilityService類一共有四個可以重寫的方法。

TestService類

public class TestService extends AccessibilityService {
    /**
     *  必須重寫的方法:此方法用了接受系統發來的event。在你注冊的event發生是被調用。在整個生命周期會被調用多次。
     */
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
    }

   /**
     *  必須重寫的方法:系統要中斷此service返回的響應時會調用。在整個生命周期會被調用多次。
     */
    @Override
    public void onInterrupt() {
    }

     /**
     *  當系統連接上你的服務時被調用
     */
    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
    }


    /**
     *  在系統要關閉此service時調用。
     */
    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }
}

2,給你的輔助服務寫一個配置文件。
res/xml/text_server_config.xml

<accessibility-service
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagDefault"
    android:canRetrieveWindowContent="true"
    android:description="@string/accessibility_description"
    android:notificationTimeout="10" />

看屬性的名字應該比較容易猜測到不同是屬性是用來干嘛的。

accessibilityEventTypes:響應那種類型的事件

accessibilityFeedbackType:用什么方式反饋給用戶

notificationTimeout:響應時間

packageNames:指定響應哪個應用的事件。如果不填則是響應所有的應用事件(如果以后寫搶紅包的輔助功能,可以只寫微信的包名)

description:輔助服務的描述信息。

3,在manifest中注冊服務。

        <service
            android:name=".TestService"
            //輔助功能的名稱
            android:label="@string/test_service_label"
            //此處必須聲明一次權限
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService" />
            </intent-filter>
            <meta-data
            //對,我就是上面寫好的配置文件
                android:name="android.accessibilityservice"
                android:resource="@xml/text_service_config" />
        </service>

4,最后,回到服務的類,TestService。在onAccessibilityEvent(AccessibilityEvent event)方法中,我們可以接收到系統發過來的事件。當然取決于我們在配置文件中選擇了我們要監聽哪些種類,哪些應用的事件了。

 public void onAccessibilityEvent(AccessibilityEvent event) {
    //得到事件的包名。如果注冊了多個應用的事件,可以在此做一個判斷。
    String packageName = event.getPackageName().toString();
    
    //得到對應的事件類型,這里有很多很多種的事件類型,具體可以自行翻閱AccessibilityEvent類中的定義。
    int eventType = event.getEventType();
    
    //得到根的view節點。可以當做當前acitivity的視圖看成是樹狀結構的(實際上也是~。~),而我們現在就得到了它的根節點。
    AccessibilityNodeInfo root = getRootInActiveWindow();
    
    //我們可以得到此節點的文字
    String rootText = root.getText().toString();
    //得到此節點的class
    String rootClass = root.getClass().toString();
    //得到子節點的和子節點總數
    root.getChild(root.getChildCount()-1);
 }
 

到這里,我們可以通過無數次遍歷,找到視圖上自己想要的那個控件了。當然,還有更加簡單的方法。

    //這兩個方法如果找不到的話,都會報錯。所以請做好對應的處理。
    root.findAccessibilityNodeInfosByText("根據文本內容查找節點");
    root.findAccessibilityNodeInfosByViewId("根據id查找節點,當然實際上很難知道id是多少~、~");

最后我們可以對控件做一些操作,比如

    //點擊操作
    root.performAction(AccessibilityNodeInfo.ACTION_CLICK);

    //滑動操作
    root.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);

好,對于輔助服務的基礎知識我們學到這里已經差不多了,如果跟著我寫了一個demo的童鞋們,可以運行一下,在設置->無障礙中把自己的輔助功能打開試試。把玩一下。


下面可以進入搶紅包的開發。

搶紅包

我們先回顧一下手動搶紅包的過程。
假設小新某天在用手機刷微博。叮叮,聽到提示聲,通知欄上顯示:“小明\n [微信紅包]恭喜發財,大吉大利”。
小新光速點了一下微信通知,手機自動跳轉到了對應的微信聊天頁面,聊天界面里正是一條橙色底色,配上紅包圖片的信息:“恭喜發財,大吉大利\n領取紅包\n微信紅包”。
腦子還沒反應過來,手指已經自動點到這條信息上,這是有一個正在加載的提示框一閃而過,然后就是正中一個大大的紅包,中間是金黃色的“開”字。
不用想了,開!看著開字轉啊轉,心急如焚。最后屏幕一閃,跳到了紅包詳情頁面,心頭大石落地,詳情頁面寫在“0.01分錢”。小新也心滿意足地回去看微博了。

我們的自動搶紅包就是要自動幫我們完成這么一個流程:
1,獲取通知欄的信息,判斷是否紅包。
2,如果屏幕關著的,先打開屏幕。
3,點擊通知,進入聊天界面
4,點擊紅包信息
5,點擊紅包中的“開”
6,返回主界面,安安靜靜了無痕跡。

先上github的地址。我是地址;大家可以直接去看代碼。代碼很簡單。無非就是遍歷找控件。

1, 得到通知欄信息
通知欄事件

AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED

可以通過event.getText()方法得到通知欄的文字。然后在與“[微信紅包]”做對比,判斷是否微信紅包。

2,
打開屏幕。如果是有屏幕鎖的。那我就沒辦法了哎,,知道的童鞋請賜教。

  /**
     * 解鎖
     */
    private void wakeAndUnlock() {
        //獲取電源管理器對象
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);

        //獲取PowerManager.WakeLock對象,后面的參數|表示同時傳入兩個值,最后的是調試用的Tag
        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright");

        //點亮屏幕
        wl.acquire(1000);

        //得到鍵盤鎖管理器對象
        KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
        kl = km.newKeyguardLock("unLock");

        //解鎖
        kl.disableKeyguard();
    }

記得釋放鍵盤管理器

 kl.reenableKeyguard();

3,通過通知欄進入微信聊天界面。

//打開微信聊天頁面
    private void openWeichaPage(AccessibilityEvent event) {
        if (event.getParcelableData() != null && event.getParcelableData() instanceof Notification) {
            //得到通知的對象
            Notification notification = (Notification) event.getParcelableData();

            //得到通知欄的信息
//            String content = notification.tickerText.toString();
//            String name = content.substring(0, content.indexOf(":"));
//            String scontent = content.substring(content.indexOf(":"), content.length());
//            Log.d("mylog", "------openWeichaPage  name: " + name + " content: " + scontent);


            //打開通知欄的intent,即打開對應的聊天界面
            PendingIntent pendingIntent = notification.contentIntent;
            try {
                pendingIntent.send();
            } catch (PendingIntent.CanceledException e) {
                e.printStackTrace();
            }
        }
    }

4,我們需要監聽頁面的變化加自己定義變量來判斷是否跳轉到了微信聊天頁面。

頁面跳轉的事件是:

 AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED

微信聊天頁面的classname:

com.tencent.mm.ui.LauncherUI

判斷的方法:

    String className = event.getClassName().toString();
    
    //是否微信聊天頁面的類
    if (className.equals(LAUCHER)) {
       findStuff();
    }

然后就是做遍歷,大體思路是調用getChild(i)找到聊天頁面中的紅包??梢韵韧ㄟ^getClassName()比較是否“android.widget.TextView”,然后通過getText()匹配文本內容。

具體方法不表。大家可以自己寫寫,不想寫可以看GitHub上我寫的代碼。

5,和上面的方法一直,判斷窗口跳轉,加遍歷找到“開”字,對,開 也是一個TextView。

6,至此就大功告成,可以返回桌面了。

 /**
     * 回到系統桌面
     */
    private void back2Home() {
        Intent home = new Intent(Intent.ACTION_MAIN);

        home.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        home.addCategory(Intent.CATEGORY_HOME);

        startActivity(home);
    }

我們的搶紅包之旅到這里就告一段落了,結束的是一次艱苦的擼代碼的時光,開啟的是千千萬萬次自動搶紅包的快感。

最后,祝大家新年 大 吉 吧!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容