Android静默安装实现方案,秒装(测试没有通过)和智能安装(实现)功能

阅读这篇博客:http://www.2cto.com/kf/201512/453537.html
感谢作者;我把他的源码还原,出现好多错误,已改好,随后附上源码
下面代码,你应该在很多地方看到过,需要root 权限,android 静默安装(测试没有通过(小米node 1s 已root)现在测试另一部手机魅族node 2)和智能安装可以安装 测试/system/app(系统级的) 中已存在的app也可以智能安装覆盖;

  Process process = Runtime.getRuntime().exec("su");
           dataOutputStream = new DataOutputStream(process.getOutputStream());
           // 执行pm install命令
           String command = "pm install -r " + apkPath + "\n";
           dataOutputStream.write(command.getBytes(Charset.forName("utf-8")));
           dataOutputStream.flush();
           dataOutputStream.writeBytes("exit\n");
           dataOutputStream.flush();
           process.waitFor();
           errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
           String msg = "";
           String line;
           // 读取命令的执行结果
           while ((line = errorStream.readLine()) != null) {
               msg += line;
           }
           Log.d("TAG", "install msg is " + msg);
           // 如果执行结果中包含Failure字样就认为是安装失败,否则就认为安装成功
           if (!msg.contains("Failure")) {
               result = true;
           }
       } catch (Exception e) {
           Log.e("TAG", e.getMessage(), e);
       } finally {
           try {
               if (dataOutputStream != null) {
                   dataOutputStream.close();
               }
               if (errorStream != null) {
                   errorStream.close();
               }
           } catch (IOException e) {
               Log.e("TAG", e.getMessage(), e);
           }
       }

智能安装就是对于看不到手机的人使用的,没有界面操作的,打开智能安装服务,检测每当窗口有活动时,就会有消息回调到onAccessibilityEvent()方法中,因此所有的逻辑都是从这里开始的。首先我们可以通过传入的AccessibilityEvent参数来获取当前事件的类型,事件的种类非常多,但是我们只需要监听TYPE_WINDOW_CONTENT_CHANGED和TYPE_WINDOW_STATE_CHANGED这两种事件就可以了,因为在整个安装过程中,这两个事件必定有一个会被触发。当然也有两个同时都被触发的可能,那么为了防止二次处理的情况,这里我们使用了一个Map来过滤掉重复事件。

接下来就是调用iterateNodesAndHandle()方法来去解析当前界面的节点了,这里我们通过递归的方式将安装界面中所有的子节点全部进行遍历,当发现按钮节点的时候就进行判断,按钮上的文字是不是“安装”、“完成”、“确定”这几种类型,如果是的话就模拟一下点击事件,这样也就相当于帮用户自动操作了这些按钮。另外从Android 4.4系统开始,用户需要将应用申请的所有权限看完才可以点击安装,因此如果我们在节点中发现了ScrollView,那就模拟一下滑动事件,将界面滑动到最底部,这样安装按钮就可以点击了。
代码如下:

public class MyAccessibilityService extends AccessibilityService  {
    Map<Integer, Boolean> handledMap=new HashMap<Integer, Boolean>();
    public MyAccessibilityService() {
    }
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
         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);
                        }
                    }
                }
            }
    }
     private boolean iterateNodesAndHandle(AccessibilityNodeInfo nodeInfo) {
            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() {
        // TODO Auto-generated method stub

    }

}

后续功能实现会再贴源码,看来好多网上的例子,都是超级复杂的,还没有demo及相应的.apk测试,希望这个给你带来方便,我花费一点时间,给你省几天时间,希望看到这个博客的人,也用这种总结,给人以方便,我们写代码会更轻松;谢谢!!
这就是主要代码;不清楚看原文链接
源码下载:http://download.csdn.net/detail/u012922981/9531003

猜你喜欢

转载自blog.csdn.net/u012922981/article/details/51499462