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的輸入內容可以記錄 聊天記錄,等等可以做個備份以方便我們的需求