简单实现了微信自动抢红包的服务,原理就是根据关键字找到相应的View, 然后自动点击。主要是用到AccessibilityService这个辅助服务,基本可以满足自动抢红包的功能,但是有些逻辑需要优化,比如,拆完一个红包后,必须手动点击返回键,才能进行下一次自动抢红包。

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.jackie.webchatenvelope" > 
 
    <application 
        android:allowBackup="true" 
        android:icon="@mipmap/ic_launcher" 
        android:label="@string/app_name" 
        android:theme="@style/AppTheme" > 
        <activity 
            android:name=".MainActivity" 
            android:label="@string/app_name" > 
            <intent-filter> 
                <action android:name="android.intent.action.MAIN" /> 
 
                <category android:name="android.intent.category.LAUNCHER" /> 
            </intent-filter> 
        </activity> 
 
        <service 
            android:enabled="true" 
            android:exported="true" 
            android:label="@string/app_name" 
            android:name=".EnvelopeService" 
            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/envelope_service_config"/> 
        </service> 
    </application> 
 
</manifest>
envelope_service_config.xml


<?xml version="1.0" encoding="utf-8"?> 
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" 
    android:accessibilityEventTypes="typeNotificationStateChanged|typeWindowStateChanged" 
    android:accessibilityFeedbackType="feedbackGeneric" 
    android:accessibilityFlags="" 
    android:canRetrieveWindowContent="true" 
    android:description="@string/accessibility_description" 
    android:notificationTimeout="100" 
    android:packageNames="com.tencent.mm" />
activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context=".MainActivity"> 
 
    <Button 
        android:id="@+id/start" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:padding="10dp" 
        android:layout_centerInParent="true" 
        android:textSize="18sp" 
        android:text="打开辅助服务"/> 
 
</RelativeLayout>

MainActivity.java

package com.jackie.webchatenvelope;   
   
import android.app.Activity;   
import android.content.Intent;   
import android.os.Bundle;   
import android.view.Menu;   
import android.view.MenuItem;   
import android.view.View;   
import android.widget.Button;   
import android.widget.Toast;   
   
public class MainActivity extends Activity {   
    private Button startBtn;   
   
    @Override   
    protected void onCreate(Bundle savedInstanceState) {   
        super.onCreate(savedInstanceState);   
        setContentView(R.layout.activity_main);   
   
        startBtn = (Button) findViewById(R.id.start);   
        startBtn.setOnClickListener(new View.OnClickListener() {   
            @Override   
            public void onClick(View v) {   
                try {   
                    //打开系统设置中辅助功能   
                    Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);   
                    startActivity(intent);   
                    Toast.makeText(MainActivity.this, "找到抢红包,然后开启服务即可", Toast.LENGTH_LONG).show();   
                } catch (Exception e) {   
                    e.printStackTrace();   
                }   
            }   
        });   
    }   
   
    @Override   
    public boolean onCreateOptionsMenu(Menu menu) {   
        // Inflate the menu; this adds items to the action bar if it is present.   
        getMenuInflater().inflate(R.menu.menu_main, menu);   
        return true;   
    }   
   
    @Override   
    public boolean onOptionsItemSelected(MenuItem item) {   
        // Handle action bar item clicks here. The action bar will   
        // automatically handle clicks on the Home/Up button, so long   
        // as you specify a parent activity in AndroidManifest.xml.   
        int id = item.getItemId();   
   
        //noinspection SimplifiableIfStatement   
        if (id == R.id.action_settings) {   
            return true;   
        }   
   
        return super.onOptionsItemSelected(item);   
    }   
}

EnvelopeService.java

package com.jackie.webchatenvelope; 
 
import android.accessibilityservice.AccessibilityService; 
import android.annotation.TargetApi; 
import android.app.Notification; 
import android.app.PendingIntent; 
import android.os.Build; 
import android.os.Handler; 
import android.util.Log; 
import android.view.accessibility.AccessibilityEvent; 
import android.view.accessibility.AccessibilityManager; 
import android.view.accessibility.AccessibilityNodeInfo; 
import android.widget.Toast; 
 
import java.util.List; 
 
/** 
 * <p>Created by Administrator</p> 
 * <p/> 
 * 抢红包外挂服务 
 */ 
public class EnvelopeService extends AccessibilityService { 
 
    static final String TAG = "Jackie"; 
 
    /** 
     * 微信的包名 
     */ 
    static final String WECHAT_PACKAGENAME = "com.tencent.mm"; 
    /** 
     * 红包消息的关键字 
     */ 
    static final String ENVELOPE_TEXT_KEY = "[微信红包]"; 
 
    Handler handler = new Handler(); 
 
    @Override 
    public void onAccessibilityEvent(AccessibilityEvent event) { 
        final int eventType = event.getEventType(); 
 
        Log.d(TAG, "事件---->" + event); 
 
        //通知栏事件 
        if (eventType == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) { 
            List<CharSequence> texts = event.getText(); 
            if (!texts.isEmpty()) { 
                for (CharSequence t : texts) { 
                    String text = String.valueOf(t); 
                    if (text.contains(ENVELOPE_TEXT_KEY)) { 
                        openNotification(event); 
                        break; 
                    } 
                } 
            } 
        } else if (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { 
            openEnvelope(event); 
        } 
    } 
 
    /*@Override 
    protected boolean onKeyEvent(KeyEvent event) { 
        //return super.onKeyEvent(event); 
        return true; 
    }*/ 
 
    @Override 
    public void onInterrupt() { 
        Toast.makeText(this, "中断抢红包服务", Toast.LENGTH_SHORT).show(); 
    } 
 
    @Override 
    protected void onServiceConnected() { 
        super.onServiceConnected(); 
        Toast.makeText(this, "连接抢红包服务", Toast.LENGTH_SHORT).show(); 
    } 
 
    private void sendNotificationEvent() { 
        AccessibilityManager manager = (AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE); 
        if (!manager.isEnabled()) { 
            return; 
        } 
        AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED); 
        event.setPackageName(WECHAT_PACKAGENAME); 
        event.setClassName(Notification.class.getName()); 
        CharSequence tickerText = ENVELOPE_TEXT_KEY; 
        event.getText().add(tickerText); 
        manager.sendAccessibilityEvent(event); 
    } 
 
    /** 
     * 打开通知栏消息 
     */ 
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 
    private void openNotification(AccessibilityEvent event) { 
        if (event.getParcelableData() == null || !(event.getParcelableData() instanceof Notification)) { 
            return; 
        } 
        //以下是精华,将微信的通知栏消息打开 
        Notification notification = (Notification) event.getParcelableData(); 
        PendingIntent pendingIntent = notification.contentIntent; 
        try { 
            pendingIntent.send(); 
        } catch (PendingIntent.CanceledException e) { 
            e.printStackTrace(); 
        } 
    } 
 
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 
    private void openEnvelope(AccessibilityEvent event) { 
        if ("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI".equals(event.getClassName())) { 
            //点中了红包,下一步就是去拆红包 
            checkKey1(); 
        } else if ("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI".equals(event.getClassName())) { 
            //拆完红包后看详细的纪录界面 
            //nonething 
        } else if ("com.tencent.mm.ui.LauncherUI".equals(event.getClassName())) { 
            //在聊天界面,去点中红包 
            checkKey2(); 
        } 
    } 
 
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 
    private void checkKey1() { 
        AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); 
        if (nodeInfo == null) { 
            Log.w(TAG, "rootWindow为空"); 
            return; 
        } 
        List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("拆红包"); 
        for (AccessibilityNodeInfo n : list) { 
            n.performAction(AccessibilityNodeInfo.ACTION_CLICK); 
        } 
    } 
 
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 
    private void checkKey2() { 
        AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); 
        if (nodeInfo == null) { 
            Log.w(TAG, "rootWindow为空"); 
            return; 
        } 
        List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("领取红包"); 
        if (list.isEmpty()) { 
            list = nodeInfo.findAccessibilityNodeInfosByText(ENVELOPE_TEXT_KEY); 
            for (AccessibilityNodeInfo n : list) { 
                Log.i(TAG, "-->微信红包:" + n); 
                n.performAction(AccessibilityNodeInfo.ACTION_CLICK); 
                break; 
            } 
        } else { 
            //最新的红包领起 
            for (int i = list.size() - 1; i >= 0; i--) { 
                AccessibilityNodeInfo parent = list.get(i).getParent(); 
                Log.i(TAG, "-->领取红包:" + parent); 
                if (parent != null) { 
                    parent.performAction(AccessibilityNodeInfo.ACTION_CLICK); 
                    break; 
                } 
            } 
        } 
    } 
}




发布评论

分享到:

IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

android项目 微博客户端 源码详解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。