这次我们来使用AccessibilityService实现一个微信抢红包的辅助工具。
先来一个简单的效果图,最后会有一个完整的效果图:
首先,先回想一下微信红包的领取流程。
1.通知栏出现微信红包的消息
2.点击通知栏,进入领取红包界面
3.点击领取红包,领取成功后,进入拆红包界面
4.拆红包,显示获得金额
5.等待下一个红包
那么根据之前学到的关于AccessibilityService的知识可以这样填写配置文件:
AccessibilityService的相关配置 xml/rob_service_config:
由于我们这里只需要监听微信产生的事件,所以packageNames属性应当填写微信的包名。
下面便是最重要的抢红包代码:
package krelve.demo.rob;
import java.util.List;
import android.accessibilityservice.AccessibilityService; import android.annotation.SuppressLint; import android.app.Notification; import android.app.PendingIntent; import android.app.PendingIntent.CanceledException; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo;
public class RobMoney extends AccessibilityService {
@Override public void onAccessibilityEvent(AccessibilityEvent event) { int eventType = event.getEventType(); switch (eventType) { case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:// 通知栏事件 List texts = event.getText(); if (!texts.isEmpty()) { for (CharSequence text : texts) { String content = text.toString(); if (content.contains("[微信红包]")) { // 监听到微信红包的notification,打开通知 if (event.getParcelableData() != null && event.getParcelableData() instanceof Notification) { Notification notification = (Notification) event .getParcelableData(); PendingIntent pendingIntent = notification.contentIntent; try { pendingIntent.send(); } catch (CanceledException e) { e.printStackTrace(); } } } } } break; case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: String className = event.getClassName().toString(); if (className.equals("com.tencent.mm.ui.LauncherUI")) { getPacket();// 领取红包 } else if (className .equals("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI")) { openPacket();// 打开红包 } break; } }
@SuppressLint("NewApi") private void openPacket() { AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); if (nodeInfo != null) { List list = nodeInfo .findAccessibilityNodeInfosByText("拆红包"); for (AccessibilityNodeInfo n : list) { n.performAction(AccessibilityNodeInfo.ACTION_CLICK); } }
}
@SuppressLint("NewApi") private void getPacket() { AccessibilityNodeInfo rootNode = getRootInActiveWindow(); if (rootNode != null) { List nodeInfos = rootNode .findAccessibilityNodeInfosByText("领取红包"); for (AccessibilityNodeInfo nodeInfo : nodeInfos) { nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK); }
} }
@Override public void onInterrupt() {
}
}
在onAccessibilityEvent中,监听AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED和AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED事件。如果是通知栏事件,那么获取通知事件的text,如果包含 [微信红包] 字样,则说明是一个红包的通知事件。 然后通过event.getParcelableData()获取Notification实例对象,调用其中的pendingintent即可。 通知栏响应事件就是打开领取红包的界面,自己写了一个模拟微信红包的demo,来方便测试。 处理完通知栏事件后,就是窗体事件了。 进入领取红包界面后,如何找到领取红包的点击按钮并实现点击呢? 1.确定当前窗体界面是领取红包界面:event.getClassName().toString() 通过判断className来确定 2.AccessibilityNodeInfo 中有这样一个方法:findAccessibilityNodeInfosByText() 所以可以通过寻找 领取红包 字样来找到领取红包的点击事件。
AccessibilityNodeInfo rootNode = getRootInActiveWindow(); if (rootNode != null) { List nodeInfos = rootNode .findAccessibilityNodeInfosByText("领取红包"); for (AccessibilityNodeInfo nodeInfo : nodeInfos) { nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK); }
}
这样就可以实现领取红包的点击。 既然已经获得红包,那么就要拆红包了。 类似领红包,拆红包只是类名和搜索的text不一样而已:
AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
if (nodeInfo != null) {
List list = nodeInfo
.findAccessibilityNodeInfosByText("拆红包");
for (AccessibilityNodeInfo n : list) {
n.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
这样就实现了一个最基本的抢红包辅助工具,剩下的细节可以慢慢实现。
最后看一下最终的效果图: