AccessibilityService之微信抢红包辅助功能实现

这次我们来使用AccessibilityService实现一个微信抢红包的辅助工具。

先来一个简单的效果图,最后会有一个完整的效果图:

AccessibilityService之微信抢红包辅助功能实现_第1张图片

 

 

首先,先回想一下微信红包的领取流程。

1.通知栏出现微信红包的消息

2.点击通知栏,进入领取红包界面

3.点击领取红包,领取成功后,进入拆红包界面

4.拆红包,显示获得金额

5.等待下一个红包

那么根据之前学到的关于AccessibilityService的知识可以这样填写配置文件:

<service
            android:name="krelve.demo.rob.RobMoney"
            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/rob_service_config" />

</service>

AccessibilityService的相关配置 xml/rob_service_config:

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeNotificationStateChanged|typeWindowStateChanged"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagDefault"
    android:canRetrieveWindowContent="true"
    android:description="@string/accessibility_description"
    android:notificationTimeout="100"
    android:packageNames="com.tencent.mm" />

由于我们这里只需要监听微信产生的事件,所以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<CharSequence> 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<AccessibilityNodeInfo> list = nodeInfo
     .findAccessibilityNodeInfosByText("拆红包");
   for (AccessibilityNodeInfo n : list) {
    n.performAction(AccessibilityNodeInfo.ACTION_CLICK);
   }
  }

 }

 @SuppressLint("NewApi")
 private void getPacket() {
  AccessibilityNodeInfo rootNode = getRootInActiveWindow();
  if (rootNode != null) {
   List<AccessibilityNodeInfo> 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<AccessibilityNodeInfo> nodeInfos = rootNode
     .findAccessibilityNodeInfosByText("领取红包");
   for (AccessibilityNodeInfo nodeInfo : nodeInfos) {
    nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
   }

  }

 

这样就可以实现领取红包的点击。 
既然已经获得红包,那么就要拆红包了。 
类似领红包,拆红包只是类名和搜索的text不一样而已:

 

AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
  if (nodeInfo != null) {
   List<AccessibilityNodeInfo> list = nodeInfo
     .findAccessibilityNodeInfosByText("拆红包");
   for (AccessibilityNodeInfo n : list) {
    n.performAction(AccessibilityNodeInfo.ACTION_CLICK);
   }
  }

 这样就实现了一个最基本的抢红包辅助工具,剩下的细节可以慢慢实现。

最后看一下最终的效果图:

 

你可能感兴趣的:(AccessibilityService之微信抢红包辅助功能实现)