微信自动抢红包源码

背景

之所以产生这个项目,是因为:

1、之前在做小车时,想通过手机来控制小车的行径,所以得要先研究下Android开发

2、某次在码代码时,错过了群里的好几个大红包,于是想着,可不可以来个自动抢红包的,省的每次都去关注手机

于是乎,就出现了这个项目了。

同时由于对这个很感兴趣,想快速的完成,所以这两个星期就把小车放下了,专来研究抢红包。

一、应该要具备哪些知识点

11.png

基础快速掌握

不懂Android开发怎么办?
学!
先去网上搜索开发自动抢红包,需要哪些材料。
最后看了好几篇文章好,核心点是AccessibilityService这么个Android组件。
好,问题来了,AccessibilityService是什么鬼?
继续查找资料,但发现,看看了几篇文章后,还是看不懂,连建个Android Project都搞不了。
于是就从Android开发基础开始看起,
网上有很多的教程,我看的是“菜鸟教程–安卓开发”,
跟着这里的教程,用业余时间看了3-4天左右,只是看到了Service那章就停了,感觉应该是差不多可以动手了。
最后能达到的效果是:
1、能使用Android Studio创建工程
2、能编写多个Activity之间通信
3、能在Activity中启动Service,且能互相通讯

然后的重点就是去理解AccessibilityService
关于AccessibilityService的具体我就不详写了,网上有很多,推荐这篇写的蛮好的:http://www.jianshu.com/p/959217070c87

这个过程,会遇到很多问题,及新的知识点,也就要各个击破了,要认真的去查询资料。
这个期间,为了分别了解每个知识点,都实验了如下项目:
1、app的自动安装
2、微信的自动回复
能做到以上两个,基本上对开发抢红包就没有什么难度了。

现在总结,利用AccessibilityService进行相关的操作,就是要理解:
1、事件响应的处理
2、app每个控件的查找

其实,有做过前端开发和桌面开发的同学,就比较容易上手了,套路几乎是一致的。

(偷下懒,思维跨度太大了,就直接上代码了,代码里也有注释)

WxHongBaoService.java

package com.example.xxh.wxhongbao;

import android.accessibilityservice.AccessibilityService;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Intent;
import android.util.Log;
import android.view.KeyEvent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

import java.io.IOException;
import java.util.List;

/**
 * Created by xxh on 2017/9/21.
 */

public class WxHongBaoService extends AccessibilityService {
    private final String TAG = "WXHONGBAO";

    private void log(String msg)
    {
        Log.i(TAG, msg);
    }

    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
        log("service connected");
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        int eventType = event.getEventType();

        switch (eventType) {
            case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
                doNotification(event);
                break;
            case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
            case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
            case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
                //doWxHome();
                findAndOpenHB();
                clickHB();
                quitDetaiHB();
                break;
        }
    }

    @Override
    public void onInterrupt() {

    }

    /**
     * 模拟back按键
     */
    private void pressBackButton(){
        AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
        if(nodeInfo == null)
            return;;
        List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/hc");
        if(list != null && list.size() > 0) {
            for(AccessibilityNodeInfo n : list) {
                n.performAction(AccessibilityNodeInfo.ACTION_CLICK);
            }
        }
    }

    /**
     * 找红包 并打开红包
     */
    private void findAndOpenHB()
    {
        AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
        if(nodeInfo == null)
            return;
        List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/a8q"); // 红包整块
        if(list != null && list.size() > 0) {
            for(AccessibilityNodeInfo n : list) {
                List<AccessibilityNodeInfo> noClick = n.findAccessibilityNodeInfosByText("领取红包"); // 未被领取
                if(noClick != null && noClick.size() > 0) {
                    for (AccessibilityNodeInfo n1 : noClick) {
                        log("***********找到***********");
                        n.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    }
                }

            }
        }
    }

    /**
     * 拆红包
     */
    private void clickHB()
    {
        AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
        if(nodeInfo == null)
            return;;
        List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/bp6");
        if(list != null && list.size() > 0) {
            for(AccessibilityNodeInfo n : list) {
                log("***********拆开***********");
                n.performAction(AccessibilityNodeInfo.ACTION_CLICK);
            }
        }
    }

    /**
     * 退出 红包详情页面  拆开红包后的页面  如果在此页面的话  有红包来  触发不了以上事件
     */
    private void quitDetaiHB()
    {
        AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
        if(nodeInfo == null)
            return;;
        List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("红包详情");
        if(list != null && list.size() > 0) {
            log("退出红包详情");
            pressBackButton();
            back2Home();
        }

    }

    /**
     * 在微信首页 打开聊天窗口
     */
    private void doWxHome()
    {
        AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
        if(nodeInfo == null)
            return;;
        List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/aja");
        if(list != null && list.size() > 0) {
            for(AccessibilityNodeInfo n : list) {
                List<AccessibilityNodeInfo> child = n.findAccessibilityNodeInfosByText("[微信红包]");
                if(child!=null && child.size()>0) {
                    log("***********打开窗口***********");
                    n.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                }
            }
        }
    }

    /**
     * 响应通知事件, 如果是红包通知, 则进入聊天界面
     */
    private void doNotification(final AccessibilityEvent event)
    {
        if(event.getParcelableData() != null && event.getParcelableData() instanceof Notification) {
            Notification notification = (Notification)event.getParcelableData();
            String content = notification.tickerText.toString();
            log("接收到通知信息: " + content);
            int idx = content.indexOf("[微信红包]");
            if(idx > 0) {
                PendingIntent pendingIntent = notification.contentIntent;
                try {
                    pendingIntent.send();
                }catch (PendingIntent.CanceledException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 回到系统桌面
     */
    private void back2Home() {
        Intent home = new Intent(Intent.ACTION_MAIN);

        home.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        home.addCategory(Intent.CATEGORY_HOME);

        startActivity(home);
    }


}

创建了一个主界面
MainActivity.java

package com.example.xxh.wxhongbao;

import android.content.Intent;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private final String TAG = "MAINACTIVITY";
    private Button open_service_btn;

    private void log(String msg)
    {
        Log.i(TAG, msg);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        open_service_btn = (Button)findViewById(R.id.open_service_btn);
        open_service_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 打开辅助服务
                final String mAction = Settings.ACTION_ACCESSIBILITY_SETTINGS;
                Intent intent = new Intent(mAction);
                startActivity(intent);
            }
        });

        if(isAccessibilitySettingsOn()) {
            Toast.makeText(this, "你的辅助服务已开启,现在就可以开心的抢红包了", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "你的辅助服务没开启,请开启", Toast.LENGTH_LONG).show();
        }
    }

    /**
     * 判断辅助服务是否开启
     */
    private boolean isAccessibilitySettingsOn()
    {
        int isEnable = 0;
        final String service = getPackageName() + "/" + WxHongBaoService.class.getCanonicalName();
        log(service);
        try {
            isEnable = Settings.Secure.getInt(getApplicationContext().getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED);
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
        }

        TextUtils.SimpleStringSplitter simpleStringSplitter = new TextUtils.SimpleStringSplitter(':');// 多个服务使用冒号隔开
        if(isEnable == 1) {
            String settingValue = Settings.Secure.getString(getApplicationContext().getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
            if(settingValue != null) {
                simpleStringSplitter.setString(settingValue);
                while (simpleStringSplitter.hasNext()) {
                    String accessibilityServcie = simpleStringSplitter.next();
                    log("["+accessibilityServcie + "]"+accessibilityServcie.length());
                    log("["+service + "]"+service.length());
                    if(accessibilityServcie.equalsIgnoreCase(service)) {
                        return true;
                    }
                }

            }
        }
        return  false;
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.xxh.wxhongbao" >

    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.REORDER_TASKS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher1"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity android:name=".MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".WxHongBaoService"
            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" />
        </service>
    </application>

</manifest>

res/xml/accessibility.xml  Accessibility配置文件

<?xml version="1.0" encoding="utf-8" ?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"

    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagDefault"
    android:canRetrieveWindowContent="true"
    android:packageNames="com.tencent.mm"
    android:notificationTimeout="100" />

发表评论