前段时间采用小米的开源代码解决了自动抢红包的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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
因为子线程不能操作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,一起来玩吧!!
|