Android开启辅助功能之后可以用AccessibilityService 去后台监控指定的app的输入内容,也可以监控到app的动作 以及通知栏的动作,
抢红包其实就根据通知栏出现了红包的通知消息,进而用程序模拟人手点击通知消息,进入红包页面,再去模拟点击红包即可
很简单的一段代码:
public class EventService extends AccessibilityService { public EventService() { } @Override public void onAccessibilityEvent(AccessibilityEvent event) { try { String inputChar= event.getText().get(0).toString(); Log.i("######", inputChar); AccessibilityNodeInfo rootNode = getRootInActiveWindow(); } catch (IndexOutOfBoundsException e) { e.printStackTrace(); } } @Override public void onInterrupt() { } }
我们还需要去注册这个service
<service android:name=".EventService" android:enabled="true" android:exported="true" android:label="@string/app_name" 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/accessibility" /> //这里是对应的配置文件 需要在res目录下创建一个名叫xml的包 </service>
xml的包下边创建一个 accessibility.xml
<?xml version="1.0" encoding="utf-8"?> <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeViewFocused|typeViewTextChanged" android:accessibilityFeedbackType="feedbackVisual" android:canRetrieveWindowContent="true" android:description="@string/aaa" android:packageNames="com.tencent.mm" //这里是被监控的app的包名 android:notificationTimeout="100" />
在安装完此程序之后 需要在 辅助设置--------->无障碍----------------->打开此程序的开关
完工 此时你可以打开指定的app去输入框里输入内容此时日志就会打印出对应的内容
对于抢红包的时候 可以根据通知栏的状态去判断是否有红包:
@Override public void onAccessibilityEvent(AccessibilityEvent event) { int eventType = event.getEventType(); switch (eventType) { case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED: handleNotification(event); //如果是红包的消息 点击通知栏的红包消息 break; case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: case AccessibilityEvent.TYPE_WINDOW_CONTENT_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(); } else if (className.equals("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI")) { close(); } break; } }
/** * 处理通知栏信息 * * 如果是微信红包的提示信息,则模拟点击 * * @param event */ private void handleNotification(AccessibilityEvent event) { List<CharSequence> texts = event.getText(); if (!texts.isEmpty()) { for (CharSequence text : texts) { String content = text.toString(); //如果微信红包的提示信息,则模拟点击进入相应的聊天窗口 if (content.contains("[微信红包]")) { if (event.getParcelableData() != null && event.getParcelableData() instanceof Notification) { Notification notification = (Notification) event.getParcelableData(); PendingIntent pendingIntent = notification.contentIntent; try { pendingIntent.send(); } catch (PendingIntent.CanceledException e) { e.printStackTrace(); } } } } } }
/** * 关闭红包详情界面,实现自动返回聊天窗口 */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) private void close() { AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); if (nodeInfo != null) { //为了演示,直接查看了关闭按钮的id List<AccessibilityNodeInfo> infos = nodeInfo.findAccessibilityNodeInfosByViewId("@id/ez"); nodeInfo.recycle(); for (AccessibilityNodeInfo item : infos) { item.performAction(AccessibilityNodeInfo.ACTION_CLICK); } } } /** * 模拟点击,拆开红包 */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) private void openPacket() { AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); if (nodeInfo != null) { //为了演示,直接查看了红包控件的id List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByViewId("@id/b9m"); //此处的是控件的xpath 可以用UIAutomator去获取 nodeInfo.recycle(); for (AccessibilityNodeInfo item : list) { item.performAction(AccessibilityNodeInfo.ACTION_CLICK);//模拟人手点击对应的控件 } } } /** * 模拟点击,打开抢红包界面 */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) private void getPacket() { AccessibilityNodeInfo rootNode = getRootInActiveWindow(); AccessibilityNodeInfo node = recycle(rootNode); node.performAction(AccessibilityNodeInfo.ACTION_CLICK); AccessibilityNodeInfo parent = node.getParent(); while (parent != null) { if (parent.isClickable()) { parent.performAction(AccessibilityNodeInfo.ACTION_CLICK); break; } parent = parent.getParent(); } } /** * 递归查找当前聊天窗口中的红包信息 * * 聊天窗口中的红包都存在"领取红包"一词,因此可根据该词查找红包 * * @param node */ public AccessibilityNodeInfo recycle(AccessibilityNodeInfo node) { if (node.getChildCount() == 0) { if (node.getText() != null) { if ("领取红包".equals(node.getText().toString())) { return node; } } } else { for (int i = 0; i < node.getChildCount(); i++) { if (node.getChild(i) != null) { recycle(node.getChild(i)); } } } return node; }
总结:
我们主要是根据AccessbilityService的回调方法去检测到对应app对应界面的事件,来过滤我们想要的信息,进入对应页面模拟人手去点击对应的控件,如此可以实现抢红包,
其实有了模拟点击我们可以做的事情就很多了(比如安装应用等等)
监控app的输入内容可以记录 聊天记录,等等可以做个备份以方便我们的需求