• Android后台监控指定app的输入内容,抢红包,模拟点击原理


         Android开启辅助功能之后可以用AccessibilityService 去后台监控指定的app的输入内容,也可以监控到app的动作 以及通知栏的动作,

    抢红包其实就根据通知栏出现了红包的通知消息,进而用程序模拟人手点击通知消息,进入红包页面,再去模拟点击红包即可

          很简单的一段代码:

    public class EventService extends AccessibilityService {
        public EventService() {
        }
    
        @Override
        public void onAccessibilityEvent(AccessibilityEvent event) {
            try {
                String inputChar= event.getText().get(0).toString();
                Log.i("######", inputChar);
                AccessibilityNodeInfo rootNode = getRootInActiveWindow();
            } catch (IndexOutOfBoundsException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void onInterrupt() {
    
        }
    
    }

    我们还需要去注册这个service

            <service
                android:name=".EventService"
                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/accessibility" />   //这里是对应的配置文件  需要在res目录下创建一个名叫xml的包
            </service>

    xml的包下边创建一个  accessibility.xml  

    <?xml version="1.0" encoding="utf-8"?>
    <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
        android:accessibilityEventTypes="typeViewFocused|typeViewTextChanged"
        android:accessibilityFeedbackType="feedbackVisual"
        android:canRetrieveWindowContent="true"
        android:description="@string/aaa"
        android:packageNames="com.tencent.mm"   //这里是被监控的app的包名
        android:notificationTimeout="100" />

    在安装完此程序之后  需要在   辅助设置--------->无障碍----------------->打开此程序的开关     

    完工    此时你可以打开指定的app去输入框里输入内容此时日志就会打印出对应的内容

      对于抢红包的时候  可以根据通知栏的状态去判断是否有红包:

    @Override
        public void onAccessibilityEvent(AccessibilityEvent event) {
            int eventType = event.getEventType();
            switch (eventType) {
                case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
                    handleNotification(event); //如果是红包的消息  点击通知栏的红包消息
                    break;
                case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
                case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
                    String className = event.getClassName().toString();
                    if (className.equals("com.tencent.mm.ui.LauncherUI")) {
                        getPacket();
                    } else if (className.equals("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI")) {
                        openPacket();
                    } else if (className.equals("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI")) {
                        close();
                    }
    
                    break;
            }
        }

      

    /**
         * 处理通知栏信息
         *
         * 如果是微信红包的提示信息,则模拟点击
         *
         * @param event
         */
        private void handleNotification(AccessibilityEvent event) {
            List<CharSequence> texts = event.getText();
            if (!texts.isEmpty()) {
                for (CharSequence text : texts) {
                    String content = text.toString();
                    //如果微信红包的提示信息,则模拟点击进入相应的聊天窗口
                    if (content.contains("[微信红包]")) {
                        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_MR2)
        private void close() {
            AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
            if (nodeInfo != null) {
                //为了演示,直接查看了关闭按钮的id
                List<AccessibilityNodeInfo> infos = nodeInfo.findAccessibilityNodeInfosByViewId("@id/ez");
                nodeInfo.recycle();
                for (AccessibilityNodeInfo item : infos) {
                    item.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                }
            }
        }
    
        /**
         * 模拟点击,拆开红包
         */
        @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
        private void openPacket() {
            AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
            if (nodeInfo != null) {
                //为了演示,直接查看了红包控件的id
                List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByViewId("@id/b9m");  //此处的是控件的xpath 可以用UIAutomator去获取
                nodeInfo.recycle();
                for (AccessibilityNodeInfo item : list) {
                    item.performAction(AccessibilityNodeInfo.ACTION_CLICK);//模拟人手点击对应的控件
                }
            }
        }
    
        /**
         * 模拟点击,打开抢红包界面
         */
        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
        private void getPacket() {
            AccessibilityNodeInfo rootNode = getRootInActiveWindow();
            AccessibilityNodeInfo node = recycle(rootNode);
    
            node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
            AccessibilityNodeInfo parent = node.getParent();
            while (parent != null) {
                if (parent.isClickable()) {
                    parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    break;
                }
                parent = parent.getParent();
            }
    
        }
    
        /**
         * 递归查找当前聊天窗口中的红包信息
         *
         * 聊天窗口中的红包都存在"领取红包"一词,因此可根据该词查找红包
         * 
         * @param node
         */
        public AccessibilityNodeInfo recycle(AccessibilityNodeInfo node) {
            if (node.getChildCount() == 0) {
                if (node.getText() != null) {
                    if ("领取红包".equals(node.getText().toString())) {
                        return node;
                    }
                }
            } else {
                for (int i = 0; i < node.getChildCount(); i++) {
                    if (node.getChild(i) != null) {
                        recycle(node.getChild(i));
                    }
                }
            }
            return node;
        }

        总结:

        我们主要是根据AccessbilityService的回调方法去检测到对应app对应界面的事件,来过滤我们想要的信息,进入对应页面模拟人手去点击对应的控件,如此可以实现抢红包,

      其实有了模拟点击我们可以做的事情就很多了(比如安装应用等等)

           监控app的输入内容可以记录 聊天记录,等等可以做个备份以方便我们的需求

  • 相关阅读:
    Linux下Apache服务器并发优化
    centos 7 mount win共享文件夹 开机自动挂载
    自学 phpredis 的心路历程
    VM虚拟机下centos7 无法上网的问题解决办法
    php headers_sent 函数的作用
    is_file 与 file_exists 的区别
    php 面向对象 中的self
    php 去除所有空格 包括中文空格圆角空格
    滑动窗口滚动条触发事件
    PHP中file_exists与is_file、is_dir的区别,以及执行效率的比较 转自#冰雪傲骨#
  • 原文地址:https://www.cnblogs.com/bimingcong/p/9723263.html
Copyright © 2020-2023  润新知