Android免Root自动安装apk

效果

要开启辅助功能并且,并且android版本在api-14或者以上.
这里写图片描述

GitHub

Afra55/TrainingFirstApp
https://github.com/Afra55/TrainingFirstApp/tree/master

参考文章

最近看到应用宝最新版也加了新功能“省心装”,觉得这玩意挺不错,就研究了下,奈何网上资料少的渣渣,便参考了如下几篇文章自己动手简单实现了下。
(1)使用Android Accessibility实现免Root自动批量安装功能
http://www.infoq.com/cn/articles/android-accessibility-installing?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global

(2)专访豌豆荚「自动装」开发团队:无需Root即可批量点击「下一步」-CSDN.NET
http://www.csdn.net/article/1970-01-01/2824737

(3)https://developer.android.com/intl/zh-cn/guide/topics/ui/accessibility/services.html

添加权限

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

在清单文件里注册service

<!--省心装-->
        <service android:name=".module.accessibility_service.MAcessibilityService"
            android:label="@string/acc_auto_install_service_name"
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
            android:enabled="@bool/atLeastIceCreamSandwich">
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService" />
            </intent-filter>
            <meta-data
                android:name="android.accessibilityservice"
                android:resource="@xml/accessibility_config" />
        </service>
  • atLeastIceCreamSandwich”是判定当前系统是否api-14及以上版本,14以下的便自己手动安装吧>~<:
    BOOLEAN

  • accessibility_config是配置文件,在res的xml文件夹下:
    这里写图片描述

配置文件

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/acc_auto_install_service_description"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFlags="flagDefault"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:notificationTimeout="100"
    android:canRetrieveWindowContent="true"
    android:packageNames="com.android.packageinstaller"
/>
  • description:是描述,在辅助功能里展示。
  • packageNames:就是要监听的包名,可以有多个,中间用逗号隔开。比如 “packageName1, packageName2”。

自定义服务

/**
 * Created by yangshuai in the 11:43 of 2015.10.22 .
 * https://developer.android.com/intl/zh-cn/guide/topics/ui/accessibility/services.html
 * 省心装服务
 */
public class MAcessibilityService extends AccessibilityService{

    /* 完成安装flag*/
    private final static int FINISH_INSTALL = 1009;

    /* 检测安装过程flag*/
    private final static int  CHECK_INSTALL = 1008;

    /* 是否执行*/
    private static boolean enable = false;

    /* 正在模拟点击*/
    private boolean clicking = false;

    /* 模拟点击的次数, 完成安装后的返回没有计算在里面*/
    private static int onClickCount = 0;

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case CHECK_INSTALL:

                    btnPerformClick((List<AccessibilityNodeInfo>)msg.obj);
                    break;
                case FINISH_INSTALL:

                    enable = false;
                    AccessibilityService service = (AccessibilityService) msg.obj;
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                        service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
                    }
                    break;
            }
        }
    };

    /**
     * 设置是否监测
     * @param ok
     */
    public static void setEnable(boolean ok){
        enable = ok;
        onClickCount = 0;
    }

    /**
     * Callback for {@link AccessibilityEvent}s.
     *
     * @param event An event.
     */
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {

        // 如果不监测,和正在模拟点击中
        if (!enable || clicking) return;

        AccessibilityNodeInfo nodeInfo = event.getSource();
        if (nodeInfo == null) {
            return;
        }
        /**
        for (int i = 0; i < nodeInfo.getChildCount(); i++) {
           Log.d("MAcessibilityService", "nodeInfo.getChild(i):" + nodeInfo.getChild(i).getText());
        }
        **/

        List<AccessibilityNodeInfo> nextBtn = null;

        if ((nextBtn = nodeInfo.findAccessibilityNodeInfosByText(getString(R.string.installing))) != null && (nextBtn.size() > 0)){   // 如果正在安装
            Log.d("wahaha", "正在安装");
            nextBtn.get(0).recycle();

        }else if((((nextBtn = nodeInfo.findAccessibilityNodeInfosByText(getString(R.string.next)))!=null && nextBtn.size() > 0) ||     // 获取下一步按钮控件
                ((nextBtn = nodeInfo.findAccessibilityNodeInfosByText(getString(R.string.install))) !=null && nextBtn.size() > 0)||       // 获取安装按钮控件
                ((nextBtn = nodeInfo.findAccessibilityNodeInfosByText(getString(R.string.done))) !=null && nextBtn.size() > 0))         // 获取完成按钮控件
                ) {

            // 模拟点击flag设置为true
            clicking = true;
            Message message = new Message();
            message.obj = nextBtn;
            message.what = CHECK_INSTALL;
            handler.sendMessageDelayed(message, 500);
        }else {

            // 判断是否完成安装
            handler.removeMessages(FINISH_INSTALL);
            Message message = new Message();
            message.what = FINISH_INSTALL;
            message.obj = this;
            handler.sendMessageDelayed(message, 1800);
        }

        nodeInfo.recycle();

    }


    /**
     * 模拟点击
     * @param nextBtn
     * @return
     */
    private boolean btnPerformClick(List<AccessibilityNodeInfo> nextBtn) {

        Log.d("MAcessibilityService", "onClickCount:" + ++onClickCount);

        AccessibilityNodeInfo nextInfo = nextBtn.get(nextBtn.size() - 1);
        if (nextInfo == null) {
            return true;
        }
        nextInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
        nextInfo.recycle();
        clicking = false;
        return false;
    }

    /**
     * Callback for interrupting the accessibility feedback.
     */
    @Override
    public void onInterrupt() {
    }
}

自定义服务中的字符串

values/strings

 <!-- 省心装-->
    <string name="install">INSTALL</string>
    <string name="installing">Installing…</string>
    <string name="done">DONE</string>
    <string name="next">NEXT</string>

values-zh-rCN/strings

 <!-- 省心装-->
    <string name="install">安装</string>
    <string name="installing">正在安装...</string>
    <string name="done">完成</string>
    <string name="next">下一步</string>

总结

如上,很简单就实现了自动安装的功能,当然这里没有对所有机型进行适配。在使用的时候要注意一点是,在使用的时候添加如下一行代码,这样服务才会进行检查:

MAcessibilityService.setEnable(true);

博客地址:http://blog.csdn.net/yang786654260/article/details/49422687

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值