QQ抢红包插件

作为一个有女朋友的人,之前跟那些20年的单身狗抢红包是屡战屡败。再加上最近群里面发红包发的厉害,又想到快要过年了,到时候还不知道群里要发好多红包,所以我将之前在网上宕的一份微信抢红包的代码修改了一下,实现了QQ抢红包!可以支持抢QQ拼手气红包,普通红包,口令红包,现在再也不怕20年单身手速的人跟我抢红包了! 
先看测试效果图: 
1.抢QQ口令红包


QQ抢红包插件实现 专业源码分享
可以看见,只要红包一发出,自动填写口令并发出,帮你将红包抢到手! 
2.抢QQ拼手气红包:


QQ抢红包插件实现 专业源码分享
拼手气红包也是一样,只要红包一发出,自动帮你把红包抢到手,是不是很爽的感觉? 
3.抢QQ好友发送的红包:



QQ抢红包插件实现 专业源码分享
只要好友或者群里的人把红包一发出,就会第一时间让你抢到红包!所以只要在群里面开启插件,抢红包从来都是百发百中!好了废话不多说了,也不吹嘘有多牛多好了,下面直接给大家上代码: 


MainActivity:  


  1. /*MainActivity中的代码基本没改变:*/
  2. public class MainActivity extends AppCompatActivity {
  3.     private final Intent mAccessibleIntent =  new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
  4.     private Button switchPlugin;
  5.    
  6.     @Overrideprotected void onCreate(Bundle savedInstanceState) {
  7.         super.onCreate(savedInstanceState);   
  8.         setContentView(R.layout.activity_main);   
  9.         switchPlugin = (Button) findViewById(R.id.button_accessible);
  10.         updateServiceStatus();
  11.     }
  12.    
  13.     /*开启插件的按钮*/
  14.     public void onButtonClicked(View view) {startActivity(mAccessibleIntent);}
  15.    
  16.     @Overrideprotected void onResume() {
  17.         super.onResume();
  18.         updateServiceStatus();
  19.     }
  20. }
  21.    
  22.     private void updateServiceStatus() {   
  23.         boolean serviceEnabled = false;   
  24.         AccessibilityManager accessibilityManager = (AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE);
  25.         List<AccessibilityServiceInfo> accessibilityServices = accessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC);   
  26.         for (AccessibilityServiceInfo info : accessibilityServices) {     
  27.             if (info.getId().equals(getPackageName() + "/.QQHongbaoService")) {         
  28.                 serviceEnabled = true;          
  29.                 break;       
  30.              }  
  31.          }
  32.          if (serviceEnabled) {   
  33.              switchPlugin.setText("关闭插件"); 
  34.              getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
  35.          } else {   
  36.              switchPlugin.setText("开启插件");   
  37.              getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);}
  38.      }
  39. }
复制代码


这里是MainActivity中的全部代码,是不是很少的样子,主要是实现了一个按钮去开启ACCESSIBILITY_SERVICE。这个插件主要就是借助AccessibilityService这个服务来实现。所以剩下的代码就都在这个服务中了! 
QQHongbaoService:

  1. public class QQHongbaoService extends AccessibilityService {
  2.   private static final String WECHAT_OPEN_EN = "Open";   
  3.   private static final String WECHAT_OPENED_EN = "You've opened";   
  4.   private final static String QQ_DEFAULT_CLICK_OPEN = "点击拆开";  
  5.   private final static String QQ_HONG_BAO_PASSWORD = "口令红包";   
  6.   private final static String QQ_CLICK_TO_PASTE_PASSWORD = "点击输入口令";  
  7.   private boolean mLuckyMoneyReceived;   
  8.   private String lastFetchedHongbaoId = null;   
  9.   private long lastFetchedTime = 0;   
  10.   private static final int MAX_CACHE_TOLERANCE = 5000;   
  11.   private AccessibilityNodeInfo rootNodeInfo;   
  12.   private List<AccessibilityNodeInfo> mReceiveNode;
  13.    
  14.   @TargetApi(Build.VERSION_CODES.KITKAT)   
  15.   public void recycle(AccessibilityNodeInfo info) {       
  16.     if (info.getChildCount() == 0) {      
  17.       /*这个if代码的作用是:匹配“点击输入口令的节点,并点击这个节点”*/   
  18.       if(info.getText()!=null&&info.getText().toString().equals(QQ_CLICK_TO_PASTE_PASSWORD)) {
  19.         info.getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK);           
  20.        }          
  21.       /*这个if代码的作用是:匹配文本编辑框后面的发送按钮,并点击发送口令*/
  22.       if (info.getClassName().toString().equals("android.widget.Button") && info.getText().toString().equals("发送")) {               
  23.         info.performAction(AccessibilityNodeInfo.ACTION_CLICK);           
  24.        }       
  25.     } else {           
  26.         for (int i = 0; i < info.getChildCount(); i++) {            
  27.            if (info.getChild(i) != null) {                     
  28.               recycle(info.getChild(i));             
  29.             }           
  30.          }      
  31.        }   
  32.     }
  33.    
  34.   @TargetApi(Build.VERSION_CODES.JELLY_BEAN)   
  35.   @Override   
  36.   public void onAccessibilityEvent(AccessibilityEvent event) {       
  37.     this.rootNodeInfo = event.getSource();       
  38.     if (rootNodeInfo == null) {           
  39.       return;      
  40.      }       
  41.     mReceiveNode = null;      
  42.     checkNodeInfo();       
  43.     /* 如果已经接收到红包并且还没有戳开 */      
  44.     if (mLuckyMoneyReceived && (mReceiveNode != null)) {          
  45.        int size = mReceiveNode.size();          
  46.        if (size > 0) {              
  47.            String id = getHongbaoText(mReceiveNode.get(size - 1));               
  48.            long now = System.currentTimeMillis();             
  49.            if (this.shouldReturn(id, now - lastFetchedTime))                     
  50.               return;              
  51.            lastFetchedHongbaoId = id;               
  52.            lastFetchedTime = now;               
  53.            AccessibilityNodeInfo cellNode = mReceiveNode.get(size - 1);                 
  54.            if (cellNode.getText().toString().equals("口令红包已拆开")) {                   
  55.               return;               
  56.            }               
  57.            cellNode.getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK);           
  58.            if (cellNode.getText().toString().equals(QQ_HONG_BAO_PASSWORD)) {
  59.                  AccessibilityNodeInfo rowNode = getRootInActiveWindow();                  
  60.            if (rowNode == null) {                     
  61.               Log.e(TAG, "noteInfo is null");                     
  62.               return;                   
  63.             } else {                    
  64.                  recycle(rowNode);                 
  65.             }               
  66.          }
  67.          mLuckyMoneyReceived = false;           
  68.           }      
  69.        } 
  70.     }
  71.    
  72.   private void checkNodeInfo() {   
  73.     if (rootNodeInfo == null) {     
  74.         return;   
  75.     }    
  76.     /* 聊天会话窗口,遍历节点匹配“点击拆开”,“口令红包”,“点击输入口令” */  
  77.     List<AccessibilityNodeInfo> nodes1 = this.findAccessibilityNodeInfosByTexts(this.rootNodeInfo, new String[]{QQ_DEFAULT_CLICK_OPEN, QQ_HONG_BAO_PASSWORD, QQ_CLICK_TO_PASTE_PASSWORD, "发送"});   
  78.     if (!nodes1.isEmpty()) {     
  79.         String nodeId = Integer.toHexString(System.identityHashCode(this.rootNodeInfo));       
  80.         if (!nodeId.equals(lastFetchedHongbaoId)) {   
  81.         mLuckyMoneyReceived = true;          
  82.         mReceiveNode = nodes1;      
  83.          }        return;   
  84.       }
  85.     }
  86.    
  87.   private String getHongbaoText(AccessibilityNodeInfo node) { 
  88.       /* 获取红包上的文本 */   
  89.       String content;  
  90.       try {       
  91.           AccessibilityNodeInfo i = node.getParent().getChild(0);       
  92.           content = i.getText().toString(); 
  93.           } catch (NullPointerException npe) {  
  94.                  return null;   
  95.               }   
  96.           return content;
  97.     }
  98.    
  99.    private boolean shouldReturn(String id, long duration) {  
  100.        // ID为空   
  101.       if (id == null) return true;   
  102.       // 名称和缓存不一致 
  103.       if (duration < MAX_CACHE_TOLERANCE && id.equals(lastFetchedHongbaoId)) {     
  104.           return true;  
  105.        }  
  106.       return false;
  107.     }
  108.    
  109.    private List<AccessibilityNodeInfo> findAccessibilityNodeInfosByTexts(AccessibilityNodeInfo nodeInfo, String[] texts) { 
  110.         for (String text : texts) {    
  111.            if (text == null) continue;     
  112.            List<AccessibilityNodeInfo> nodes = nodeInfo.findAccessibilityNodeInfosByText(text);    
  113.            if (!nodes.isEmpty()) {        
  114.                if (text.equals(WECHAT_OPEN_EN) && !nodeInfo.findAccessibilityNodeInfosByText(WECHAT_OPENED_EN).isEmpty()) {             
  115.                     continue;        
  116.                 }           
  117.                 return nodes;     
  118.             } 
  119.           }   
  120.         return new ArrayList<>();
  121.     }
  122.    
  123.     @Override
  124.     public void onInterrupt() {}
  125. }
复制代码


QQHongbaoService的全部代码也在这里,代码不多。首先,在这个服务中主要是通过findAccessibilityNodeInfosByText这个方法去获我们需要的节点;然后用performAction(AccessibilityNodeInfo.ACTION_CLICK)这个方法去点击红包节点,关键思路大概就是这样!另外如果是口令红包,我们需要先按照上面的步骤将红包戳开,然后通过performAction(AccessibilityNodeInfo.ACTION_CLICK)去点击输入口令,最后再通过点击去发送即可实现!QQHongbaoService需要在AndroidManifest.xml文件中注册, 
注册的<application>节点如下图:



QQ抢红包插件实现 专业源码分享

总体来看,只是将微信抢红包的代码做了少量的修改,在这里要感谢各位大神对微信抢红包源码的贡献!最后也希望这篇文章能给大家有所帮助,在抢红包大战中虐死单身狗,再也不怕你20年的单身手速了!!! 

原文地址


猜你喜欢

转载自blog.csdn.net/qq_17486399/article/details/51035581