关于APP自动化安装(初探)

仅android端而言,是有一个模式的叫作 “无障碍模式”
实现这个“无障碍模式”须要如下步骤:html

1.在res/xml目录下新建一个accessibility_service_config.xml文件java

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeAllMask" android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFlags="flagDefault" android:canRetrieveWindowContent="true" android:description="@string/accessibility_service_description" android:packageNames="com.android.packageinstaller" />
<!-- packageNames指定咱们要监听哪一个应用程序下的窗口活动, 这里写com.android.packageinstaller表示监听Android系统的安装界面。 description指定在无障碍服务当中显示给用户看的说明信息, 上图中360手机助手的一大段内容就是在这里指定的。 accessibilityEventTypes指定咱们在监听窗口中能够模拟哪些事件, 这里写typeAllMask表示全部的事件都能模拟。 accessibilityFlags能够指定无障碍服务的一些附加参数, 这里咱们传默认值flagDefault就行。 accessibilityFeedbackType指定无障碍服务的反馈方式, 实际上无障碍服务这个功能是Android提供给一些残疾人士使用的, 好比说盲人不方便使用手机,就能够借助无障碍服务配合语音反馈来操做手机, 而咱们实际上是不须要反馈的,所以随便传一个值就能够,这里传入feedbackGeneric。 最后canRetrieveWindowContent指定是否容许咱们的程序读取窗口中的节点和内容, 必须写true。 -->

2.在string.xml文件中写一下description中指定的内容:node

<string name="accessibility_service_description">
    请电机右上角的开启/关闭按钮

    开启后能自动安装应用,省去繁琐点击

    提示:
    打开系统服务室,系统会弹出例行的隐私警告。本软件承诺不会经过此服务收集任何用户隐私,请放心使用

    此服务在Android4.1如下系统不生效
    </string>

3.修改AndroidManifest.xml文件,在里面配置无障碍服务:android

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />  
<application>

...

 <service
            android:name="com.***.***.service.MyAccessibilityService"
            android:label="个人智能安装"
            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_config" />
        </service>
    </application>

注:这部分配置的内容多数是固定的,必需要声明一个android.permission.BIND_ACCESSIBILITY_SERVICE的权限,且必需要有一个值为android.accessibilityservice.AccessibilityService的action,而后咱们经过将刚才建立的配置文件指定进去。web

4.接下来就是要去实现智能安装功能的具体逻辑了,建立一个MyAccessibilityService类并继承自AccessibilityService,代码以下所示:app

public class MyAccessibilityService extends AccessibilityService {

    @SuppressLint("UseSparseArrays")
    Map<Integer, Boolean> handledMap = new HashMap<Integer, Boolean>();

    public MyAccessibilityService() {
    }

    /* 每当窗口有活动时,就会有消息回调到onAccessibilityEvent()方法中, * 所以全部的逻辑都是从这里开始的。首先咱们能够经过传入的AccessibilityEvent * 参数来获取当前事件的类型,事件的种类很是多,可是咱们只须要监听 * TYPE_WINDOW_CONTENT_CHANGED和TYPE_WINDOW_STATE_CHANGED这两种事件就能够了, * 由于在整个安装过程当中,这两个事件一定有一个会被触发。固然也有两个同时都被触发的可能 * ,那么为了防止二次处理的状况,这里咱们使用了一个Map来过滤掉重复事件。*/
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        Log.e("onAccessibilityEvent", "onAccessibilityEvent");
        AccessibilityNodeInfo nodeInfo = event.getSource();
        if (nodeInfo != null) {
            int eventType = event.getEventType();
            if (eventType== AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED ||
                    eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
                if (handledMap.get(event.getWindowId()) == null) {
                    boolean handled = iterateNodesAndHandle(nodeInfo);
                    if (handled) {
                        handledMap.put(event.getWindowId(), true);
                    }
                }
            }
        }
    }

    /** * 接下来就是调用iterateNodesAndHandle()方法来去解析当前界面的节点了, * 这里咱们经过递归的方式将安装界面中全部的子节点所有进行遍历, * 当发现按钮节点的时候就进行判断,按钮上的文字是否是“安装”、 * “完成”、“肯定”这几种类型,若是是的话就模拟一下点击事件, * 这样也就至关于帮用户自动操做了这些按钮。另外从Android 4.4系统开始, * 用户须要将应用申请的全部权限看完才能够点击安装, * 所以若是咱们在节点中发现了ScrollView,那就模拟一下滑动事件,将界面滑动到最底部, * 这样安装按钮就能够点击了。 */
    private boolean iterateNodesAndHandle(AccessibilityNodeInfo nodeInfo) {
        Log.e("iterateNodesAndHandle", "iterateNodesAndHandle");
        if (nodeInfo != null) {
            int childCount = nodeInfo.getChildCount();
            if ("android.widget.Button".equals(nodeInfo.getClassName())) {
                String nodeContent = nodeInfo.getText().toString();
                Log.d("TAG", "content is " + nodeContent);
                if ("安装".equals(nodeContent)
                        || "完成".equals(nodeContent)
                        || "肯定".equals(nodeContent)) {
                    nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    return true;
                }
            } else if ("android.widget.ScrollView".equals(nodeInfo.getClassName())) {
                nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
            }
            for (int i = 0; i < childCount; i++) {
                AccessibilityNodeInfo childNodeInfo = nodeInfo.getChild(i);
                if (iterateNodesAndHandle(childNodeInfo)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void onInterrupt() {
    }

}

5.固然,使用以前要先进这个设置界面将功能启用ide

//打开智能安装设置
                Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
                startActivity(intent);

这里写图片描述
这里写图片描述

以后再打开安装包就能够实现自动安装了。
demo代码的话,由于懒得摘除现有demo中多余部分,事后会在后面的文章中发出连接;
其实这只是做为一个知识积累,简化了许多步骤,在前人的路上搬过来的轮子。在这里感谢这个地址的原做者:
http://www.2cto.com/kf/201512/453537.html
谢谢,共勉;svg