手记

微信抢红包-快人一步

写在前面

眼看快过年了,先祝大家新年快乐,本篇是今年最后一篇文章,想想过年到了,微信红包肯定少不了,但是每次都是比人家慢了一步,所以上网搜了一下,确实很多自动抢红包的,但是担心有一些流氓软件存在一些后门,所以还是决定自己撸一遍,其实在半年前就已经实现过类似的功能,这次权当整理了;

环境要求

微信 v6.5.4

前提工作

在开始编码前我们需要弄清楚微信的某个具体布局的view id是多少,这里我用的是android studio自带的分析工具,很好用,手机到了你要分析的页面后,点击AS的Tools->Android->Android Device Monitor;
在你连上手机后点击Dump view Hierarchy for UI Automator后会出来一个和你手机上一样的界面,点击某个view之后会有对应的text、resource-id,我们需要通过text或者resource-id去实现自动点击,下面对应的属性是checked表示这个view是否可以点击,下面类似的是android的基础知识就不一一解释了,分析好所有页面后开始编码;

开始编码

首选在res文件夹下新建xml文件夹,然后新建xml文件,名字随意,只要后面写在AndroidManifest.xml中对应一样即可,例:

1

2

3

4

5

6

7

8

<?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:canRetrieveWindowContent="true"

    android:description="@string/accessibility_description"

      android:notificationTimeout="100"

    android:packageNames="com.tencent.mm" />

其实看字段应该能看懂什么意思notificationTimeout是通知超时时间,packageNames是你要监听的应用包名,其它的就不一一介绍了;

接下来新建一个extends AccessibilityService的service类,然后我们在onAccessibilityEvent函数中做文章:
我们可以通过event.getEventType();拿到事件的类型,例:

1

2

3

4

5

6

7

8

9

10

11

12

int eventType = event.getEventType();

        switch (eventType) {

            case   AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:

                                                 // 通知栏事件

                break;

            case   AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:

                    //窗体状态改变

                break;

            case AccessibilityEvent.TYPE_VIEW_SCROLLED:

                    //滚动

                break;

        }

好吧,都是很简单的功能,我觉得不必要一点点去讲解代码了,后面会给出源码下载地址,这里我讲一下实现思路:
1、手机解锁(如果是锁屏的情况下,必须要无密码)
2、点击通知栏
3、点击红包item
4、开启红包
5、锁屏(如果刚开始是锁屏的情况下)
步骤不多,可以说比较清晰简单的;
下面给出全部代码,例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

public class QinagHongBaoServier extends AccessibilityService {

    private static final String TAG = "Jackie";

    /**

     * 微信的包名

     */

    private static final String WECHAT_PACKAGENAME = "com.tencent.mm";

    /**

     * 红包消息的关键字

     */

    private static final String ENVELOPE_TEXT_KEY = "[微信红包]";

    /**

     * 在单人或者群聊页面,默认可以点击,也就是可以监听view的变化

     */

    private boolean CHAT_PAGE_CLICK = true;

    /**

     * 判断是不是消息通知栏点击进来的

     */

    private boolean NOTIFICATION_CLICK = false;

    /**

     * 判断是否锁屏

     */

    private boolean LOCKED = false;

    @Override

    public void onAccessibilityEvent(AccessibilityEvent   event) {

        int eventType = event.getEventType();

        switch (eventType) {

            case   AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:// 通知栏事件

                if (isScreenLocked()) {

                    //判断是否锁屏  是的话解锁

                    LOCKED = true;

                    wakeAndUnlock();

                }

                  List<CharSequence> texts = event.getText();

                if (!texts.isEmpty()) {

                    for (CharSequence t : texts) {

                        String   text = String.valueOf(t);

                        if (text.contains(ENVELOPE_TEXT_KEY)) {

                              NOTIFICATION_CLICK = true;

                              openNotification(event);

                            break;

                        }

                    }

                }

                break;

            case   AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED://窗体状态改变

                //窗体发生变化

                if (CHAT_PAGE_CLICK &&   NOTIFICATION_CLICK) {

                      openEnvelope(event);

                }

                break;

            case AccessibilityEvent.TYPE_VIEW_SCROLLED:

                if (CHAT_PAGE_CLICK &&   NOTIFICATION_CLICK) {

                      openEnvelope(event);

                }

                break;

        }

    }

    @Override

    public void onInterrupt() {

    }

    /**

     * 打开通知栏消息

     */

    private void openNotification(AccessibilityEvent   event) {

        if (event.getParcelableData() != null && event.getParcelableData() instanceof Notification) {

            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())) {

            //点中了红包,下一步就是去拆红包222222

            checkKey1();

        } else if ("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI".equals(event.getClassName())) {

            //拆完红包后看详细的纪录界面33333

            //拆完啦

            Toast.makeText(this, "抢完啦", Toast.LENGTH_SHORT).show();

            //设置不监听单人聊天页面监听

            CHAT_PAGE_CLICK = false;

            //把标识设回原来的状态

            NOTIFICATION_CLICK = false;

            //模拟点击返回

            onBackButton();

            //抢完红包返回一秒内不点击,为了绕开返回监听到view变化又TM给点进来了

            Handler handler = new Handler();

              handler.postDelayed(runnable, 1000);

            //锁屏

            releaseLocked();

        } else if ("android.widget.ListView".equals(event.getClassName())) {

            //在聊天界面,去点中红包11111

            checkKey2();

        }

    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)

    private void checkKey1() {

        AccessibilityNodeInfo   nodeInfo = getRootInActiveWindow();

        if (nodeInfo == null) {

            Log.w(TAG, "rootWindow为空");

            return;

        }                                                                                 //

          List<AccessibilityNodeInfo> list =   nodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/bi3");

        for (AccessibilityNodeInfo n : list) {

              n.performAction(AccessibilityNodeInfo.ACTION_CLICK);

        }

    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)

    private void checkKey2() {

        AccessibilityNodeInfo   nodeInfo = getRootInActiveWindow();

        if (nodeInfo == null) {

            Log.w(TAG, "rootWindow为空");

            return;

        }

          List<AccessibilityNodeInfo> list =   nodeInfo.findAccessibilityNodeInfosByText("领取红包");

        if (list.size() > 0) {

            //领取最新的红包

            for (int i = list.size() - 1; i >= 0; i--) {

                  AccessibilityNodeInfo parent = list.get(i).getParent();

                if (parent != null) {

                    parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);

                    break;

                }

            }

        }

    }

    private Runnable runnable = new Runnable() {

        @Override

        public void run() {

            CHAT_PAGE_CLICK = true;

            Log.i("xxxxxxxx", "我变回来啦");

        }

    };

    /**

     * 点击back返回,TMD,模拟back按键不知道为什么失败了,反正微信界面有back点击它也一样,可能就响应速度有点差别

     */

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)

    private void onBackButton() {

        AccessibilityNodeInfo   nodeInfo = getRootInActiveWindow();

        if (nodeInfo != null) {

              List<AccessibilityNodeInfo> list =   nodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/gw");

            if (list.size() > 0) {

                list.get(0).performAction(AccessibilityNodeInfo.ACTION_CLICK);

            }

        }

    }

    /**

     * 回到系统桌面

     */

    private void back2Home() {

        Intent home = new Intent(Intent.ACTION_MAIN);

          home.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        home.addCategory(Intent.CATEGORY_HOME);

        startActivity(home);

    }

    /**

     * 系统是否在锁屏状态

     *

     * @return

     */

    private boolean isScreenLocked() {

        KeyguardManager   keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);

        return   keyguardManager.inKeyguardRestrictedInputMode();

    }

    /**

     * 解锁手机

     */

    private KeyguardManager.KeyguardLock kl;

    private void wakeAndUnlock() {

        //获取电源管理器对象

        PowerManager pm =   (PowerManager) getSystemService(Context.POWER_SERVICE);

        //获取PowerManager.WakeLock对象,后面的参数|表示同时传入两个值,最后的是调试用的Tag

        PowerManager.WakeLock wl =   pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP |   PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright");

        //点亮屏幕

        wl.acquire(1000);

        //得到键盘锁管理器对象

        KeyguardManager km =   (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);

        kl = km.newKeyguardLock("unLock");

        //解锁

        kl.disableKeyguard();

    }

    /**

     * 重新锁屏

     */

    private void releaseLocked() {

        if (LOCKED && kl != null) {

            android.util.Log.d("maptrix", "release the lock");

            //得到键盘锁管理器对象

            kl.reenableKeyguard();

            LOCKED = false;

        }

    }

}

最后记得在AndroidManifest.xml中加入权限等,例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

<application

        android:allowBackup="true"

        android:icon="@mipmap/icon"

        android:label="@string/app_name"

        android:supportsRtl="true"

        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:name=".QinagHongBaoServier"

            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/envelope_service_config" />

        </service>

    </application>

测试抢红包

到设置里打开你前面对应的无障碍服务,一般是在更多设置->无障碍->你的服务名称,开启即可;
                                               

DEMO地址

总结

OK,大功告成,功能还是很简单的,基于这种无障碍服务可以做很多事情(当然,包括一些流氓行为,或者可以微信自动不断搜索添加好友等,这个比较有利于微商吧),好了,文章先到这里,如果自己实现起来确实有问题的,可以下载demo查看;

原文链接:http://www.apkbus.com/blog-719059-63039.html

0人推荐
随时随地看视频
慕课网APP