Android開發-進階:實現微信自動搶紅包的程序

簡單實現了微信自動搶紅包的服務,原理就是根據關鍵字找到相應的View, 然後自動點擊。主要是用到AccessibilityService這個輔助服務,基本可以滿足自動搶紅包的功能,但是有些邏輯需要優化,比如,拆完一個紅包後,必須手動點擊返回鍵,才能進行下一次自動搶紅包。

AndroidManifest.xml

[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.jackie.webchatenvelope" >  
  4.   
  5.     <application  
  6.         android:allowBackup="true"  
  7.         android:icon="@mipmap/ic_launcher"  
  8.         android:label="@string/app_name"  
  9.         android:theme="@style/AppTheme" >  
  10.         <activity  
  11.             android:name=".MainActivity"  
  12.             android:label="@string/app_name" >  
  13.             <intent-filter>  
  14.                 <action android:name="android.intent.action.MAIN" />  
  15.   
  16.                 <category android:name="android.intent.category.LAUNCHER" />  
  17.             </intent-filter>  
  18.         </activity>  
  19.   
  20.         <service  
  21.             android:enabled="true"  
  22.             android:exported="true"  
  23.             android:label="@string/app_name"  
  24.             android:name=".EnvelopeService"  
  25.             android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">  
  26.             <intent-filter>  
  27.                 <action android:name="android.accessibilityservice.AccessibilityService"/>  
  28.             </intent-filter>  
  29.             <meta-data  
  30.                 android:name="android.accessibilityservice"  
  31.                 android:resource="@xml/envelope_service_config"/>  
  32.         </service>  
  33.     </application>  
  34.   
  35. </manifest>  
envelope_service_config.xml

[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:accessibilityEventTypes="typeNotificationStateChanged|typeWindowStateChanged"  
  4.     android:accessibilityFeedbackType="feedbackGeneric"  
  5.     android:accessibilityFlags=""  
  6.     android:canRetrieveWindowContent="true"  
  7.     android:description="@string/accessibility_description"  
  8.     android:notificationTimeout="100"  
  9.     android:packageNames="com.tencent.mm" />  
activity_main.xml

[java] view plain copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:paddingBottom="@dimen/activity_vertical_margin"  
  6.     android:paddingLeft="@dimen/activity_horizontal_margin"  
  7.     android:paddingRight="@dimen/activity_horizontal_margin"  
  8.     android:paddingTop="@dimen/activity_vertical_margin"  
  9.     tools:context=".MainActivity">  
  10.   
  11.     <Button  
  12.         android:id="@+id/start"  
  13.         android:layout_width="wrap_content"  
  14.         android:layout_height="wrap_content"  
  15.         android:padding="10dp"  
  16.         android:layout_centerInParent="true"  
  17.         android:textSize="18sp"  
  18.         android:text="打開輔助服務"/>  
  19.   
  20. </RelativeLayout>  

MainActivity.java

[java] view plain copy
  1. package com.jackie.webchatenvelope;    
  2.     
  3. import android.app.Activity;    
  4. import android.content.Intent;    
  5. import android.os.Bundle;    
  6. import android.view.Menu;    
  7. import android.view.MenuItem;    
  8. import android.view.View;    
  9. import android.widget.Button;    
  10. import android.widget.Toast;    
  11.     
  12. public class MainActivity extends Activity {    
  13.     private Button startBtn;    
  14.     
  15.     @Override    
  16.     protected void onCreate(Bundle savedInstanceState) {    
  17.         super.onCreate(savedInstanceState);    
  18.         setContentView(R.layout.activity_main);    
  19.     
  20.         startBtn = (Button) findViewById(R.id.start);    
  21.         startBtn.setOnClickListener(new View.OnClickListener() {    
  22.             @Override    
  23.             public void onClick(View v) {    
  24.                 try {    
  25.                     //打開系統設置中輔助功能    
  26.                     Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);    
  27.                     startActivity(intent);    
  28.                     Toast.makeText(MainActivity.this"找到搶紅包,然後開啓服務即可", Toast.LENGTH_LONG).show();    
  29.                 } catch (Exception e) {    
  30.                     e.printStackTrace();    
  31.                 }    
  32.             }    
  33.         });    
  34.     }    
  35.     
  36.     @Override    
  37.     public boolean onCreateOptionsMenu(Menu menu) {    
  38.         // Inflate the menu; this adds items to the action bar if it is present.    
  39.         getMenuInflater().inflate(R.menu.menu_main, menu);    
  40.         return true;    
  41.     }    
  42.     
  43.     @Override    
  44.     public boolean onOptionsItemSelected(MenuItem item) {    
  45.         // Handle action bar item clicks here. The action bar will    
  46.         // automatically handle clicks on the Home/Up button, so long    
  47.         // as you specify a parent activity in AndroidManifest.xml.    
  48.         int id = item.getItemId();    
  49.     
  50.         //noinspection SimplifiableIfStatement    
  51.         if (id == R.id.action_settings) {    
  52.             return true;    
  53.         }    
  54.     
  55.         return super.onOptionsItemSelected(item);    
  56.     }    
  57. }  

EnvelopeService.java

[java] view plain copy
  1. package com.jackie.webchatenvelope;  
  2.   
  3. import android.accessibilityservice.AccessibilityService;  
  4. import android.annotation.TargetApi;  
  5. import android.app.Notification;  
  6. import android.app.PendingIntent;  
  7. import android.os.Build;  
  8. import android.os.Handler;  
  9. import android.util.Log;  
  10. import android.view.accessibility.AccessibilityEvent;  
  11. import android.view.accessibility.AccessibilityManager;  
  12. import android.view.accessibility.AccessibilityNodeInfo;  
  13. import android.widget.Toast;  
  14.   
  15. import java.util.List;  
  16.   
  17. /** 
  18.  * <p>Created by Administrator</p> 
  19.  * <p/> 
  20.  * 搶紅包外掛服務 
  21.  */  
  22. public class EnvelopeService extends AccessibilityService {  
  23.   
  24.     static final String TAG = "Jackie";  
  25.   
  26.     /** 
  27.      * 微信的包名 
  28.      */  
  29.     static final String WECHAT_PACKAGENAME = "com.tencent.mm";  
  30.     /** 
  31.      * 紅包消息的關鍵字 
  32.      */  
  33.     static final String ENVELOPE_TEXT_KEY = "[微信紅包]";  
  34.   
  35.     Handler handler = new Handler();  
  36.   
  37.     @Override  
  38.     public void onAccessibilityEvent(AccessibilityEvent event) {  
  39.         final int eventType = event.getEventType();  
  40.   
  41.         Log.d(TAG, "事件---->" + event);  
  42.   
  43.         //通知欄事件  
  44.         if (eventType == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {  
  45.             List<CharSequence> texts = event.getText();  
  46.             if (!texts.isEmpty()) {  
  47.                 for (CharSequence t : texts) {  
  48.                     String text = String.valueOf(t);  
  49.                     if (text.contains(ENVELOPE_TEXT_KEY)) {  
  50.                         openNotification(event);  
  51.                         break;  
  52.                     }  
  53.                 }  
  54.             }  
  55.         } else if (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {  
  56.             openEnvelope(event);  
  57.         }  
  58.     }  
  59.   
  60.     /*@Override 
  61.     protected boolean onKeyEvent(KeyEvent event) { 
  62.         //return super.onKeyEvent(event); 
  63.         return true; 
  64.     }*/  
  65.   
  66.     @Override  
  67.     public void onInterrupt() {  
  68.         Toast.makeText(this"中斷搶紅包服務", Toast.LENGTH_SHORT).show();  
  69.     }  
  70.   
  71.     @Override  
  72.     protected void onServiceConnected() {  
  73.         super.onServiceConnected();  
  74.         Toast.makeText(this"連接搶紅包服務", Toast.LENGTH_SHORT).show();  
  75.     }  
  76.   
  77.     private void sendNotificationEvent() {  
  78.         AccessibilityManager manager = (AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE);  
  79.         if (!manager.isEnabled()) {  
  80.             return;  
  81.         }  
  82.         AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);  
  83.         event.setPackageName(WECHAT_PACKAGENAME);  
  84.         event.setClassName(Notification.class.getName());  
  85.         CharSequence tickerText = ENVELOPE_TEXT_KEY;  
  86.         event.getText().add(tickerText);  
  87.         manager.sendAccessibilityEvent(event);  
  88.     }  
  89.   
  90.     /** 
  91.      * 打開通知欄消息 
  92.      */  
  93.     @TargetApi(Build.VERSION_CODES.JELLY_BEAN)  
  94.     private void openNotification(AccessibilityEvent event) {  
  95.         if (event.getParcelableData() == null || !(event.getParcelableData() instanceof Notification)) {  
  96.             return;  
  97.         }  
  98.         //以下是精華,將微信的通知欄消息打開  
  99.         Notification notification = (Notification) event.getParcelableData();  
  100.         PendingIntent pendingIntent = notification.contentIntent;  
  101.         try {  
  102.             pendingIntent.send();  
  103.         } catch (PendingIntent.CanceledException e) {  
  104.             e.printStackTrace();  
  105.         }  
  106.     }  
  107.   
  108.     @TargetApi(Build.VERSION_CODES.JELLY_BEAN)  
  109.     private void openEnvelope(AccessibilityEvent event) {  
  110.         if ("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI".equals(event.getClassName())) {  
  111.             //點中了紅包,下一步就是去拆紅包  
  112.             checkKey1();  
  113.         } else if ("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI".equals(event.getClassName())) {  
  114.             //拆完紅包後看詳細的紀錄界面  
  115.             //nonething  
  116.         } else if ("com.tencent.mm.ui.LauncherUI".equals(event.getClassName())) {  
  117.             //在聊天界面,去點中紅包  
  118.             checkKey2();  
  119.         }  
  120.     }  
  121.   
  122.     @TargetApi(Build.VERSION_CODES.JELLY_BEAN)  
  123.     private void checkKey1() {  
  124.         AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();  
  125.         if (nodeInfo == null) {  
  126.             Log.w(TAG, "rootWindow爲空");  
  127.             return;  
  128.         }  
  129.         List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("拆紅包");  
  130.         for (AccessibilityNodeInfo n : list) {  
  131.             n.performAction(AccessibilityNodeInfo.ACTION_CLICK);  
  132.         }  
  133.     }  
  134.   
  135.     @TargetApi(Build.VERSION_CODES.JELLY_BEAN)  
  136.     private void checkKey2() {  
  137.         AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();  
  138.         if (nodeInfo == null) {  
  139.             Log.w(TAG, "rootWindow爲空");  
  140.             return;  
  141.         }  
  142.         List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("領取紅包");  
  143.         if (list.isEmpty()) {  
  144.             list = nodeInfo.findAccessibilityNodeInfosByText(ENVELOPE_TEXT_KEY);  
  145.             for (AccessibilityNodeInfo n : list) {  
  146.                 Log.i(TAG, "-->微信紅包:" + n);  
  147.                 n.performAction(AccessibilityNodeInfo.ACTION_CLICK);  
  148.                 break;  
  149.             }  
  150.         } else {  
  151.             //最新的紅包領起  
  152.             for (int i = list.size() - 1; i >= 0; i--) {  
  153.                 AccessibilityNodeInfo parent = list.get(i).getParent();  
  154.                 Log.i(TAG, "-->領取紅包:" + parent);  
  155.                 if (parent != null) {  
  156.                     parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);  
  157.                     break;  
  158.                 }  
  159.             }  
  160.         }  
  161.     }  
  162. }  
發佈了26 篇原創文章 · 獲贊 5 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章