android中的静默安装其实就是在用户不知情,且不影响用户操作,不弹出系统安装页面的情况下,悄悄地将应用安装好。常规的来讲,系统在安装应用的时候,会提示用户授权所牵扯到的权限。而当使用静默安装的时候,用户是看不到这些权限的,相当于强迫用户接受这些权限。因此,在官方看来,这种危险的行为,是不应该开放给开发者的。
考虑到让用户点击安装对话框的体验比较差的问题,我们可以通过借鉴360助手的解决方案。两种方案:智能安装(不需要root权限)和秒装(需要root权限)。今天我们主讲第一种,不需要root权限的方法。
当手机未root的时候,需要借助android的无障碍服务来实现智能安装。步骤:①、首先在res/xml目录下新建一个accessibility_service_config.xml文件,如图-1。
其中,packageNames指定我们要监听哪个应用程序下的窗口活动,这里写com.android.packageinstaller表示监听Android系统的安装界面。description指定在无障碍服务当中显示给用户看的说明信息,上图中360手机助手的一大段内容就是在这里指定的。accessibilityEventTypes指定我们在监听窗口中可以模拟哪些事件,这里写typeAllMask表示所有的事件都能模拟。accessibilityFlags可以指定无障碍服务的一些附加参数,这里我们传默认值flagDefault就行。accessibilityFeedbackType指定无障碍服务的反馈方式,实际上无障碍服务这个功能是Android提供给一些残疾人士使用的,比如说盲人不方便使用手机,就可以借助无障碍服务配合语音反馈来操作手机,而我们其实是不需要反馈的,因此随便传一个值就可以,这里传入feedbackGeneric。最后canRetrieveWindowContent指定是否允许我们的程序读取窗口中的节点和内容,必须写true。②、记得在string.xml文件中写一下description中指定的内容,如下图-2所示:
③、修改AndroidManifest.xml文件,在里面配置无障碍服务。如图-3.
这部分配置的内容多数是固定的,必须要声明一个android.permission.BIND_ACCESSIBILITY_SERVICE的权限,且必须要有一个值为android.accessibilityservice.AccessibilityService的action,然后我们通过将刚才创建的配置文件指定进去。④、去实现智能安装功能的具体逻辑,创建一个MyAccessibilityService类并继承自AccessibilityService,代码如下图-4和图-5所示:
代码并不复杂,我们来解析一下。每当窗口有活动时,就会有消息回调到onAccessibilityEvent()方法中,因此所有的逻辑都是从这里开始的。首先我们可以通过传入的AccessibilityEvent参数来获取当前事件的类型,事件的种类非常多,但是我们只需要监听TYPE_WINDOW_CONTENT_CHANGED和TYPE_WINDOW_STATE_CHANGED这两种事件就可以了,因为在整个安装过程中,这两个事件必定有一个会被触发。当然也有两个同时都被触发的可能,那么为了防止二次处理的情况,这里我们使用了一个Map来过滤掉重复事件。
接下来就是调用iterateNodesAndHandle()方法来去解析当前界面的节点了,这里我们通过递归的方式将安装界面中所有的子节点全部进行遍历,当发现按钮节点的时候就进行判断,按钮上的文字是不是“安装”、“完成”、“确定”这几种类型,如果是的话就模拟一下点击事件,这样也就相当于帮用户自动操作了这些按钮。另外从Android 4.4系统开始,用户需要将应用申请的所有权限看完才可以点击安装,因此如果我们在节点中发现了ScrollView,那就模拟一下滑动事件,将界面滑动到最底部,这样安装按钮就可以点击了。
最后,回到MainActivity中,来增加对智能安装功能的调用,如下所示:
当点击了开启智能安装服务按钮时,我们通过Intent跳转到系统的无障碍服务界面,在这里启动智能安装服务。当点击了智能安装按钮时,我们通过Intent跳转到系统的安装界面,之后所有的安装操作都会自动完成了。