您的位置:首页 > 移动开发

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

2016-07-29 13:51 155 查看
仅android端而言,是有一个模式的叫做 “无障碍模式”

实现这个“无障碍模式”需要以下步骤:

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

<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中指定的内容:

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

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

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

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


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

<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,然后我们通过将刚才创建的配置文件指定进去。

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

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.当然,使用之前要先进这个设置界面将功能启用

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






之后再打开安装包就可以实现自动安装了。

demo代码的话,因为懒得摘除现有demo中多余部分,过后会在后面的文章中发出链接;

其实这只是作为一个知识积累,简化了许多步骤,在前人的路上搬过来的轮子。在这里感谢这个地址的原作者:

http://www.2cto.com/kf/201512/453537.html

谢谢,共勉;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 自动化 app 安装
相关文章推荐