在这个科技迅猛发展的时代,手机已经成为了人们生活中必不可少的工具。但是随着手机应用的不断增加,我们需要安装的应用也变得越来越多,频繁的弹窗和更新提示也让人感到烦躁。为了解决这个问题,许多人开始探索如何实现手机的静默安装,即不需要用户干预就能完成的安装方式。在安卓系统中,利用静默安装脚本便可轻松实现静默安装,本文将对其进行详细探讨。
安卓静默安装脚本
root权限下的adb直接安装system权限下使用packageinstallerAccessibilityService识别点击https://programming.vip/docs/android-silent-installation-implementation.html
实际上第三种方法也不能说是静默安装,只能算自动安装,毕竟整个过程是有安装弹窗的
关于AccessibilityService 网上已经有很多文章了,这里也不再赘述
关于第三种基本方法可以参考以下代码
https://github.com/gaoyan10/android-silent-installer/blob/master/app/src/main/java/com/yan/androidsilentinstaller/SilentInstallAccessibilityService.java
接下来重点讲下在做静默安装过程中遇到的坑
AccessibilityService的使用AccessibilityService需要在设置中的无障碍里面手动开启,不需要通过启动APP来启动。也就是说当你在无障碍选项栏选择打开的那一刻你的AccessibilityService就已经启动了,Service开启后就会监听在accessibilityservice config里面声明的package。
一般来说应用关闭会导致已经开启的无障碍服务关闭。可以考虑开启一个前台通知来增加存活。
当初很红的抢红包软件背后的 Accessibility 服务及启动原理
Service Conifg关于service的设定都会包含在accessibility_service_config.xml这个文件中。接下来讲下几个重要的点
packageName这个代表你的Service要监听的应用包名,多个包名用逗号隔开。一般来说网上的代码这里都是填的com.android.packageinstaller。实际上PackageInstaller通常来说是有两种包名的,一种是com.android.packageinstaller,另一种是com.google.android.pakcageinstaller。并且在某些设备的安装中会用到其他的包。
如果你的service启动了,但没反应,请检查安装过程中是否有其他的activity,通常可以使用adb shell dumpsys activity top | findstr ACTIVITY 或者是UI Automator Tool来查看包名。
accessibilityFlags通常这个flag都填的flagDefault,实际上可能会导致有些event不触发。在UI控件的设置中可以设置是否对于accesibility重要,如果这里不设置的话,不重要的事件将不会传入onAccessibilityEvent。
经过对多个设备适配后,我目前是这么设置这个xml文档的,这已经适用于绝大多数设备了。
<?xml version="1.0" encoding="utf-8"?> <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:packageNames="com.google.android.packageinstaller,com.android.packageinstaller,com.coloros.safecenter,com.miui.securitycenter,com.oplus.appdetail,com.oplus.safecenter,android" android:description="@string/accessibility_service_description" android:accessibilityEventTypes="typeAllMask" android:accessibilityFlags="flagIncludeNotImportantViews|flagDefault|flagRetrieveInteractiveWindows|flagIncludeNotImportantViews|flagReportViewIds|flagRequestEnhancedWebAccessibility" android:accessibilityFeedbackType="feedbackGeneric" android:canRetrieveWindowContent="true" android:canPerformGestures="true"> </accessibility-service>Safecenter/Securitycenter
某些设备在安装应用的时候需要输入安装密码,这个弹窗是不在packageinstaller里面的,一般来说会叫safecenter或者securitycenter,比如小米的叫com.miui.securitycenter,oppo的叫com.coloros.safecenter或者com.oplus.safecenter,这个也需要在config里面包括,同时还需要做Input的输入操作。
安全应用推荐国内很多设备会有安全应用推荐这个东西,如下图,建议在设置中关闭
安全应用推荐顺带一提 有一些老的设备比如Oppo A73是关闭不掉应用推荐的,这个只能在代码里面去做特殊处理了。
一般来说推荐都会是三到四个,这里可以先用findAccessibilityNodeInfosByText查找安装Button,如果发现很多就进行特殊处理,并且一般来说安装推荐会在完成界面,不会和安装按钮出现在同一个界面,至少目前没发现例外。
Oppo设备Oppo设备与其他设备不同,主要分为了两种类型。
第一种是把安装按钮嵌套在了其他包,而不是packageinstaller,通常来说会在com.oplus.appdetail里面,在conifg里面声明就好
第二种比较阴间,一般来说去遍历ui树都是用onAccessibilityEvent里面传入的event去获取UI根节点,然后再从根节点向下遍历,但有些机型(比如Oppo R11)用这种遍历方式是获取不到安装按钮的,只能获取到取消安装按钮,可以看到用UI Automator Viewer获取到的UI树下面是没有安装按钮的。
UI Automator Viewer视图虽然不知道Oppo做了什么让安装按钮无法遍历,但实际上安装按钮仍然可以通过findAccessibilityNodeInfosByText获取。但这个时候第二个问题就出来了,获取到的Button无法点击,这里说的无法点击并不是指Button的isClickable被设置为了false,通过log仍然可以看到Button是clickable,对搜索到的Button执行performAction后是没有反应了,而这并非findAccessibilityNodeInfosByText的问题。实际上通过findAccessibilityNodeInfosByText搜索到的其他Button,比如说退出安装是可以点击的。只能认为oppo对安装Button做了什么处理。
为了解决上面的问题,只能寻求其他方法。还好AccessibilityService在API 24后提供了gesture功能,得益于这项功能我们能够实现在屏幕上模拟点击而不需要像以前那样获取root使用adb模拟。关于gesture的使用,网上就能搜得到。在之前我们提到了可以通过findAccessibilityNodeInfosByText获取到安装按钮的nodeinfo,这里我们只需要使用getBoundsInScreen获取node的rect就能得知其在屏幕上的坐标。
应用商店推荐当你在安装应用商店已有的软件时,packageinstaller会弹出提示询问是否要安装商店最新的版本,需要注意此时处理的字段。通常来说需要处理的字段如下:
安装2. 继续安装
3. 继续安装旧版本
4. 重新安装
5. 完成
6. 确定
ADB禁用软件某些设备的安装实际上是由packageinstaller跳转到了自家的安全软件或者什么管家之类的,比如INFINIX某些机型上有个叫Phone Master的软件。一般来说这类软件都是系统自带的,权限是system级别的,正常关是关不掉的,这里可以使用adb命令来禁用app。
adb shell pm disable-user [PACKAGENAME]
一般来说关掉后就可以直接静默安装了,而且还不会随重启自启动。
在这个时代,手机扮演着越来越重要的角色,许多人都希望能够快速、方便地安装应用程序。而静默安装,作为一种便捷的安装方式,也成为了越来越多人的选择。通过使用安卓静默安装脚本,我们可以轻松地实现静默安装,并解决了繁琐的手动操作问题。这样的便利性,让我们的手机使用更加顺畅,也大大提升了我们的生活和工作效率。