问题背景
最近换了个测试机,用了VIVO。但是每次安装的时候都必须点击一次继续安装。验证影响效率。为了解决这个问题做了一些研究
效果
失败之路
辅助功能
本来想使用AccessibilityService来实现这个功能,但是我配置了packageNames为空,也没办法检测到安装界面。估计是系统定制了。不支持com.android.packageinstaller.PackageInstallerActivity 的监听
别人的方法
在网上找到下面这个解决方案,亲测无效。
VivoAutoInstallAPK:一键自动化安装APK的利器
成功之路
最后通过gradle脚本来实现的。在每次安装app的时候会执行 app:assembelDebug 任务。只需要在这个任务最后挂载应该任务使用adb来实现模拟点击就可以了。这个脚本会判断是不是vivo手机,如果不是的话,不会执行模拟点击任务。
gradle插件
// 自定义的任务
task tapAfterBuild {
doLast {
isVivo(new Action<Boolean>() {
@Override
void execute(Boolean isVivo) {
if(isVivo){
//启动一个线程,等待3秒,然后每秒钟点击一次自动安装,最多10次
new Thread(new Runnable() {
@Override
void run() {
Thread.sleep(3000)
for(int i=0;i<10;i++){
println("执行模拟点击 i="+i)
executeCommand("点击继续安装","adb shell input tap 360 1500",null);
Thread.sleep(1000)
}
}
}).start()
}
}
})
}
}
void isVivo(Action<Boolean> resultAction){
executeCommand("检测是不是vivo手机","adb shell getprop | grep \"product.manufacturer\"",new Action<String>() {
@Override
void execute(String s) {
if(s!=null&&s.toLowerCase().contains("vivo")){
resultAction.execute(true)
}else{
resultAction.execute(false)
}
}
})
}
// 定义一个方法执行命令,并在执行完毕后调用提供的Action<String>回调
def executeCommand(String opName, String commandLine, Action<String> callback) {
println "执行操作:" + opName + ",命令为" + commandLine;
// 读取输出
def split = commandLine.split("\\s+");
println Arrays.toString(split)
// 使用ProcessBuilder执行命令
ProcessBuilder processBuilder = new ProcessBuilder(commandLine.split("\\s+")) // 分割命令和参数
Process process = processBuilder.start()
def result= getResult(process.inputStream)
if (process.exitValue() != 0) {
// 如果退出码不为0,则可能包含错误信息
result += "\nError: Command exited with error code ${process.exitValue()}"
}
println "结果为:"+result
// 调用回调并传入结果字符串
if (callback != null) {
callback.execute(result)
}
}
String getResult(InputStream inputStream) {
BufferedReader bufferedReader = null;
StringBuffer sb=new StringBuffer();
try {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "gbk"));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
};
// 配置 afterEvaluate 逻辑
afterEvaluate {
android.applicationVariants.all { variant ->
if (variant.buildType.name.equals('debug')) {
variant.assemble.finalizedBy(tapAfterBuild)
}
}
}
// 可以在这里添加其他相关的任务或配置
使用
将上面的文件保存为autoInstallApkInVIVO.gradle 和app的build.gradle放在一起
最后一句话导入即可。
// 使用脚本实现在vivo手机上自动点击继续安装,提高开发效率。
// 如果不是vivo手机就不执行相关操作,对性能无影响
apply from: 'autoInstallApkInVIVO.gradle'
遇到的坑
无法获得命令输出
本来想在autoInstallApkInVIVO.gradle中起一个线程,然后在线程中不断查询当前页面是否是安装页面也就是activity为com.android.packageinstaller.PackageInstallerActivity ,可以借助我之前的博客来实现这个功能获取正在运行的Activity 包括其中的fragment 工具。但是实测在gradle中启动一个线程以后,再去执行命令,无法获得命令的输出。
获取点击位置
分享个经验。怎么知道要模拟点击位置的坐标。
打开开发者选择中的如下开关
就可以获取坐标了,坐标在左上角