Android辅助功能之自动安装apk

原理:1、当有apk安装时,包名为com.android.packageinstaller的apk会弹出安装授权框,会引起界面窗口的变化

2.AccessbilityService可以监听到界面窗口的变化


步骤:

1.写一个类继承AccessibilityService并重写相关方法,在方法onAccessibilityEvent中监听窗口事件的变化


AccessibilityNodeInfo rootNode = getRootInActiveWindow();   //获取窗口


int count = rootNode.getChildCount();      //获取组件的数目


 List<AccessibilityNodeInfo> nodeInfos = nodeInfo1.findAccessibilityNodeInfosByText("下一步");  //安装文字内容查找控件


 accessibilityNodeInfo.getClassName()            //获取组件的名称


  accessibilityNodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);   //执行点击事件


代码如下:

package com.example.zjhl.myapplication;

import android.accessibilityservice.AccessibilityService;
import android.annotation.TargetApi;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.os.Build;
import android.os.PowerManager;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Toast;

import java.util.List;

/**
 * Created by zjhl on 2017/10/28.
 */
public class AutoReplyService extends AccessibilityService {

    private boolean canGet = false;//能否点击红包
    private boolean enableKeyguard = true;//默认有屏幕锁

    //窗口状态
    private static final int WINDOW_NONE = 0;
    private static final int WINDOW_LAUNCHER = 3;
    //当前窗口
    private int mCurrentWindow = WINDOW_NONE;

    //锁屏、解锁相关
    private KeyguardManager km;
    private KeyguardManager.KeyguardLock kl;
    //唤醒屏幕相关
    private PowerManager pm;
    private PowerManager.WakeLock wl = null;

    private boolean isInstall;


    //唤醒屏幕和解锁
    private void wakeAndUnlock(boolean unLock) {
        if (unLock) {
            //若为黑屏状态则唤醒屏幕
            if (!pm.isScreenOn()) {
                //获取电源管理器对象,ACQUIRE_CAUSES_WAKEUP这个参数能从黑屏唤醒屏幕
                wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "bright");
                //点亮屏幕
                wl.acquire();
            }
            //若在锁屏界面则解锁直接跳过锁屏
            if (km.inKeyguardRestrictedInputMode()) {
                //设置解锁标志,以判断抢完红包能否锁屏
                enableKeyguard = false;
                //解锁
                kl.disableKeyguard();
            }
        } else {
            //如果之前解过锁则加锁以恢复原样
            if (!enableKeyguard) {
                //锁屏
                kl.reenableKeyguard();
            }
            //若之前唤醒过屏幕则释放之使屏幕不保持常亮
            if (wl != null) {
                wl.release();
                wl = null;
            }
        }
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        int eventType = event.getEventType();
        System.out.println("onAccessibilityEvent..............................."+eventType);
        switch (eventType) {
            //第一步:监听通知栏消息
            case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
                System.out.println("onAccessibilityEvent.......................................TYPE_NOTIFICATION_STATE_CHANGED.");
                break;
            //第二步:监听是否进入apk安装界面
            case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
                System.out.println("TYPE_WINDOW_STATE_CHANGED...............................");
                AccessibilityNodeInfo rootNode = getRootInActiveWindow();
                if (rootNode != null) {
                    int count = rootNode.getChildCount();
                    for (int i = 0; i < count; i++) {
                        final AccessibilityNodeInfo nodeInfo = rootNode.getChild(i);
                        if (nodeInfo == null) {
                            continue;
                        }
                        System.out.println("nodeInfo.getClassName.............................." + nodeInfo.getClassName());
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                clickNode(nodeInfo);
                            }
                        }).start();
                    }
                }
                break;

            case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
                System.out.println("onAccessibilityEvent.......................................TYPE_WINDOW_CONTENT_CHANGED");
                break;
        }

    }

    private void clickNode(AccessibilityNodeInfo nodeInfo) {
        //“下一步”和“安装”都是button
        if ("android.widget.Button".equals(nodeInfo.getClassName()) && !isInstall) {
            isInstall = true;
            System.out.println("TYPE_WINDOW_STATE_CHANGED...............................1");
            AccessibilityNodeInfo nodeInfo1 = getRootInActiveWindow();
            System.out.println("TYPE_WINDOW_STATE_CHANGED...............................2");
            if (nodeInfo1 != null) {
                System.out.println("TYPE_WINDOW_STATE_CHANGED...............................3");
                //找到"下一步"
                List<AccessibilityNodeInfo> nodeInfos = nodeInfo1.findAccessibilityNodeInfosByText("下一步");
                System.out.println("下一步.................................");
                if (nodeInfos.size() == 0) {
                    nodeInfos = nodeInfo1.findAccessibilityNodeInfosByText("安装");
                    System.out.println("安装.................................");
                    if (nodeInfos.size() == 0) {
                        System.out.println("完成.................................");
                        nodeInfos = nodeInfo1.findAccessibilityNodeInfosByText("完成");
                    }
                }
                System.out.println("TYPE_WINDOW_STATE_CHANGED...............................4..." + nodeInfos.size());
                for (int j = 0; j < nodeInfos.size(); j++) {
                    System.out.println("recycle.................................." + j);
                    AccessibilityNodeInfo accessibilityNodeInfo = nodeInfos.get(j);
                    System.out.println("TYPE_WINDOW_STATE_CHANGED...............................5..." + accessibilityNodeInfo.getClassName());
                    //找到图片最外层的位置
//                    if (!isInstall) {
                        if ("android.widget.Button".equals(accessibilityNodeInfo.getClassName())) {
                            accessibilityNodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                            System.out.println("TYPE_WINDOW_STATE_CHANGED...............................clicked...");
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            isInstall = false;
                            clickNode(nodeInfo);
                            break;
                        }
                }
            }
        }
    }

    @Override
    public void onInterrupt() {
        System.out.println("onInterrupt.............................");

    }

    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
        Log.i("demo", "开启");
        System.out.println("onServiceConnected.......................................");
        //获取电源管理器对象
        pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        //得到键盘锁管理器对象
        km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
        //初始化一个键盘锁管理器对象
        kl = km.newKeyguardLock("unLock");
        Toast.makeText(this, "_已开启应用自动安装服务_", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        System.out.println("onDestroy.......................................");
        Log.i("demo", "关闭");
        wakeAndUnlock(false);
        Toast.makeText(this, "_已关闭应用自动安装服务_", Toast.LENGTH_LONG).show();
    }

}


2.在配置文件中进行服务的配置

   <service
            android:name=".AutoReplyService"
            android:enabled="true"
            android:exported="true"
            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/auto_reply_service_config"/>
        </service>

3.在res的xml文件夹下配置文件auto_reply_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="flagDefault"
    android:canRetrieveWindowContent="true"
    android:notificationTimeout="100"
    android:packageNames="com.tencent.mobileqq,com.android.packageinstaller"
    />
    <!--android:packageNames="com.example.zjhl.myapplication,com.UCMobile,com.wandoujia.phoenix2,com.wandoujia.phoenix2.usbproxy,eu.chainfire.supersu,com.mediatek.voiceunlock,com.kingouser.com.fragment" -->

4.运行后在辅助功能中手动开启服务MyAccessibilityApplication服务,直接运行后当有apk安装时会自动模拟点击


  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值