前段時間採用小米的開源代碼解決了自動搶紅包的bug,從而能淡定的搶微信紅包了。最近支付寶咻一咻搶紅包呵呵領福又火了一把,於是在業餘寫了一個自動咻一咻的輔助。這個輔助真的就解放了雙手,搶紅包不帶這麼累的,手指點的累死也不一定能咻出什麼東西來。廢話不多說,開始分析。
看咻一咻的界面,我通過Android Device Monitor外加代碼打印,發現的那個圓形按鈕是一個Button類型組件,界面其它部分都沒有Button,於是我想到最簡單的獲取要點擊的Node的方法就是如下:
//篩選出咻咻的button,進行不停的點擊
private AccessibilityNodeInfo getButtonInfo(AccessibilityNodeInfo parent){
if(parent != null && parent.getChildCount() > 0){
for(int i = 0 ;i < parent.getChildCount() ;i++){
AccessibilityNodeInfo node = parent.getChild(i);
if("android.widget.Button".equals(node.getClassName())){
return node;
}
}
}
return null;
}
然後在AccessibilityEvent的窗口狀態變化事件中實現按鈕的無限點擊:
if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED){
//進入咻一咻界面
if("com.alipay.android.wallet.newyear.activity.MonkeyYearActivity".equals(event.getClassName())){
isCanCyclingClick = true;
AccessibilityNodeInfo btn = getButtonInfo(getRootInActiveWindow());
if(btn != null){
dontStopClick(btn);
//wait(100);
//btn.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}else{
...
}
可以看到我在這裏通過發生事件的某個Activity類名(com.alipay.android.wallet.newyear.activity.MonkeyYearActivity)來判斷進入了咻一咻界面。然後在TYPE_WINDOW_STATE_CHANGED的事件中判斷,是進入這個activity才進行自動點擊的操作。
一開始我的無限自動點擊是採用while(true)的形式實現,後來發現了一個問題,就是Android中四大組件都是運行在UI線程的,這裏我們在AccessibilityService中運行無限點擊動作,其實也是發生在UI線程,這在Android中是很忌諱的,於是我輔助的App的Activity出現了白屏,也就是傳說的ANR,於是很多事情都發生的很詭異不正常了。
自然而然,解決方案是採用子線程,常見的操作是Thread+Handler模式,這裏我偷懶使用簡單的Timer定時器,這個在這裏很應景。於是就有了下面的自動點擊代碼:
private static final int MSG_NODE_CLICK = 0x110;
//是否能夠不停點擊咻咻的開關
private boolean isCanCyclingClick = false;
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what == MSG_NODE_CLICK){
AccessibilityNodeInfo btnNode = (AccessibilityNodeInfo) msg.obj;
btnNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
};
//定時器
private Timer timer;
private void dontStopClick(final AccessibilityNodeInfo btn){
if(timer == null){
timer= new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if(isCanCyclingClick){
Message m = mHandler.obtainMessage(MSG_NODE_CLICK, btn);
mHandler.sendMessage(m);
}
}
},100,100);
}
}
因爲子線程不能操作UI,所以使用了Handler幫忙傳輸數據(AccessibilityNodeInfo)。然後在Handler的handleMessage()方法中調用節點的點擊方法: btnNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
講到這裏,就已經基本上實現了自動點擊了。
但是在點擊過程中,會出現一個彈框,比如下面的一種情況,而且彈框內容還是不停的隨機變化的:
彈窗的出現會妨礙到自動點擊,因爲咻一咻的按鈕被遮住了。而且這個彈窗有可能是紅包或者是五福,需要領取的。因爲出現機率太小,我暫時沒法做測試。現在的處理方式,就是出現彈框,自動在1.5秒內(這樣自己可以手動領福或紅包)返回消失,然後自動繼續無限咻一咻:
if("android.app.Dialog".equals(event.getClassName())){//彈窗是Dialog
isCanCyclingClick = false;
wait(1500);
performGlobalAction(GLOBAL_ACTION_BACK);
}
private void wait(int microSeconds){
try {
Thread.sleep(microSeconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
上面這段代碼也是在AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED事件中處理的。
自此,基本實現好了支付寶自動咻一咻的功能。注意,在xml的配置中,要加上支付寶的包名,以讓它和微信一同成爲監控對象。同時咻一咻,同時搶微信紅包。
android:packageNames=”com.tencent.mm,com.eg.android.AlipayGphone”。
項目源碼地址:RedPack。
開始玩Android Studio,開始更多的玩github,一起來玩吧!!
PS:
由於現在只在5.0上測試通過,多人反映4.x和5.1都無效,今天我找了很多方案,包括看了4.x和5.x的相關源碼,確實有一些改動。但對於爲什麼在其它地方無法點擊還是不甚清楚。不過發現使用adb 命令發送事件可以讓咻一咻的按鈕進行點擊,是在4.1的系統上測試的。命令是adb shell input keyevent 66(或者adb shell 之後,input keyevent 66),也就是發送回車按鍵KEYCODE_ENTER。
至於在代碼中的實現,大家可以嘗試下。權限問題也是蠻煩人的,赫赫。