android 使用AccessibilityService 自动安装应用

转自:https://blog.csdn.net/proud2005/article/details/50157807

AccessibilityService为一个响应用户发送AccessibilityEvent事件的服务类,主要用作对于一些辅助功能的实现中。对于某些方面有缺陷的人群,可以通过辅助功能反馈给用户。

使用

1、在项目中配置service

 <service
            android:name=".MyAccessibilityService"
            android:label="@string/acc_service_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/phone_accessibility" />
        </service>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

android:permission=”android.permission.BIND_ACCESSIBILITY_SERVICE” 
辅助功能所需的权限

2.MyAccessibilityService 代码

import android.accessibilityservice.AccessibilityService;
import android.view.accessibility.AccessibilityEvent;

public class MyAccessibilityService extends AccessibilityService {

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onInterrupt() {
        // TODO Auto-generated method stub

    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

常需重写的方法 
onServiceConnected():绑定服务所用方法,一些初始化的操作放在这里面,如语音播报等 。 
onAccessibilityEvent(AccessibilityEvent event):响应AccessibilityEvent的事件,在用户操作的过程中,系统不断的发送。 
public void onInterrupt():打断获取事件的过程,本例中暂不适用。

3.res/xml目录添加以下文件,对应于service配置的meta-data 
android:name=”android.accessibilityservice”

<?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:packageNames="com.android.packageinstaller"
    android:canRetrieveWindowContent="true"
    android:description="@string/accessibility_service_description"
    android:notificationTimeout="100" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

packageNames :响应某个应用的时间,包名为应用的包名;可以用String[]对象传入多包。如果不设置,默认响应所有应用的事件。本例设置只响应安装应用的包名。 
eventTypes = AccessibilityEvent.TYPES_ALL_MASK:响应时间的类型,事件分很多种:单击、长按、滑动等,需要指定,我设置了所有事件都响应:TYPES_ALL_MASK。 
feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN:设置回馈给用户的方式,是语音播出还是振动。这个我们稍后尝试配置一些TTS引擎,让它发音。 
cessibilityServiceInfo.notificationTimeout = 1000:看意思就能明白,响应时间的设置。 
description:在手机设置 辅助功能 开启时 提示的的文字描述 
canRetrieveWindowContent 不设为true AccessibilityEvent.getSource()获取的对象即为空,获取窗口的内容

要执行需先开启服务

开启服务

设置 辅助功能 就能看到安装的 
这里写图片描述 
没问题的话开启后就能在onAccessibilityEvent 获取到事件了

获取按纽并点击执行

package cn.chinagps.gblocation.component;

import java.util.List;

import cn.chinagps.gblocation.utils.android.LogToastUtils;

import android.accessibilityservice.AccessibilityService;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

/**
 * 实现静默安装升级
 * 
 * @author proud2008
 * 
 */
public class AutoInstallAccessibilityService extends AccessibilityService {

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        log(event.toString());
        checkInstall(event);

    }

    private void log(String string) {
        LogToastUtils.log(getClass(), "AutoInstallAccessibilityService:"
                + string);

    }

    /**
     * 检查是否是要安装应用的标题
     * 
     * @param source
     * @param title
     * @return
     */
    private boolean checkTitle(AccessibilityNodeInfo source, String title) {
        List<AccessibilityNodeInfo> titleList = source
                .findAccessibilityNodeInfosByText(title);
        for (AccessibilityNodeInfo node : titleList) {
            Log.d("test", node.toString());
            if (node.getClassName().equals("android.widget.TextView")) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否需要安装应用,并执行
     * @param event
     */
    private void checkInstall(AccessibilityEvent event) {
        // source不为空
        boolean notNull = event.getSource() != null;
        if (notNull) {
            // 当前界面为安装界面
            boolean installPage = event.getPackageName().equals(
                    "com.android.packageinstaller");
            if (installPage) {
                // 当前标题为应用标题
                boolean thisApk = checkTitle(event.getSource(), "***");
                if (thisApk) {
                    doInstall(event);
                }
            }
        }

    }

    /**
     * 执行 安装 并打开应用
     * 
     * @param event
     */
    private void doInstall(AccessibilityEvent event) {
        List<AccessibilityNodeInfo> unintall_nodes = event.getSource()
                .findAccessibilityNodeInfosByText("安装");
        if (unintall_nodes != null && !unintall_nodes.isEmpty()) {
            AccessibilityNodeInfo node;
            for (int i = 0; i < unintall_nodes.size(); i++) {
                node = unintall_nodes.get(i);
                if (node.getClassName().equals("android.widget.Button")
                        && node.isEnabled()) {
                    node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                }
            }
        }

        List<AccessibilityNodeInfo> next_nodes = event.getSource()
                .findAccessibilityNodeInfosByText("下一步");
        if (next_nodes != null && !next_nodes.isEmpty()) {
            AccessibilityNodeInfo node;
            for (int i = 0; i < next_nodes.size(); i++) {
                node = next_nodes.get(i);
                if (node.getClassName().equals("android.widget.Button")
                        && node.isEnabled()) {
                    node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                }
            }
        }

        List<AccessibilityNodeInfo> ok_nodes = event.getSource()
                .findAccessibilityNodeInfosByText("打开");
        if (ok_nodes != null && !ok_nodes.isEmpty()) {
            AccessibilityNodeInfo node;
            for (int i = 0; i < ok_nodes.size(); i++) {
                node = ok_nodes.get(i);
                if (node.getClassName().equals("android.widget.Button")
                        && node.isEnabled()) {
                    node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                }
            }
        }
    }

    @Override
    public void onInterrupt() {
        // TODO Auto-generated method stub

    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值