当前位置: 首页 > news >正文

[RK3288][Android6.0] 调试笔记 --- 系统自带预置第三方APK方法

Platform: RK3288
OS: Android 6.0
Kernel: 3.10.92

Rockchip默认提供了机制来预置第三方APK, 方法很简单:
1. 在device/rockchip/rk3288创建preinstall目录(如果要可卸载,那就创建preinstall_del目录)
2. 将你要预安装的APK放进此目录即可

其中Android11里TARGET_DEVICE_DIR地址在build/make/core/board_config.mk定义

下面看下实现原理过程:
device/rockchip/common/device.mk中有:

ifneq ($(strip $(TARGET_DEVICE)), )TARGET_DEVICE_DIR=$(shell test -d device && find device -maxdepth 4 -path '*/$(TARGET_DEVICE)/BoardConfig.mk')TARGET_DEVICE_DIR := $(patsubst %/,%,$(dir $(TARGET_DEVICE_DIR)))$(shell python device/rockchip/common/auto_generator.py $(TARGET_DEVICE_DIR) system_app)$(shell python device/rockchip/common/auto_generator.py $(TARGET_DEVICE_DIR) preinstall)$(shell python device/rockchip/common/auto_generator.py $(TARGET_DEVICE_DIR) preinstall_del)-include $(TARGET_DEVICE_DIR)/system_app/preinstall.mk-include $(TARGET_DEVICE_DIR)/preinstall/preinstall.mk-include $(TARGET_DEVICE_DIR)/preinstall_del/preinstall.mk
endif

注意:$(shell test -d device && find device -maxdepth 4 -path '*/$(TARGET_DEVICE)/BoardConfig.mk')

  • 功能逻辑‌:
  • 使用test -d device检查device目录是否存在
  • 若存在则通过find命令在device目录下递归搜索(最大深度4层)匹配*/$(TARGET_PRODUCT)/BoardConfig.mk路径的文件
  • 最终将结果赋值给ARGET_DEVICE_DIR变量
  • 关键组件‌:
  • $(shell ...)是Makefile执行shell命令的语法
  • -maxdepth 4限制搜索深度为4级子目录
  • $(TARGET_PRODUCT)是Android编译系统预定义的设备产品名称变量

auto_generator.py是个python脚本,用于生成Android.mk和preinstall.mk文件,

def main(argv):preinstall_dir = os.path.join(argv[1] + '/' + argv[2])if os.path.exists(preinstall_dir):#Use to define modules for installmakefile_path = preinstall_dir + '/Android.mk'#Use to include modulesinclude_path = preinstall_dir + '/preinstall.mk'if os.path.exists(makefile_path):os.remove(makefile_path)if os.path.exists(include_path):os.remove(include_path)makefile = file(makefile_path, 'w')includefile = file(include_path, 'w')makefile.write("LOCAL_PATH := $(my-dir)\n\n")for root, dirs, files in os.walk(preinstall_dir):for file_name in files:p = re.compile(r'\S*(?=.apk\b)')found = p.search(file_name)if found:makefile.write(templet %(found.group(), argv[2]))includefile.write('PRODUCT_PACKAGES += %s\n' %found.group())makefile.close()includefile.close()

Android.mk用于制定编译规则,如我在preinstall目录下放了个AVSourceTester.apk,那么生成的文件内容是

LOCAL_PATH := $(my-dir)include $(CLEAR_VARS)
LOCAL_MODULE := AVSourceTester
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_PATH := $(TARGET_OUT)/preinstall
LOCAL_SRC_FILES := $(LOCAL_MODULE)$(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_DEX_PREOPT := false
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
include $(BUILD_PREBUILT)

preinstall.mk内容如下:
PRODUCT_PACKAGES += AVSourceTester

编译系统之后,生成路径是
out/target/product/rk3288/system/preinstall/AVSourceTester/AVSourceTester.apk

系统开机之后会调用copyDirectory()@PackageManagerService.java

  File preinstallAppDir = new File(Environment.getRootDirectory(), "preinstall");File preinstallAppDelDir = new File(Environment.getRootDirectory(),"preinstall_del");if ((!SystemProperties.getBoolean("persist.sys.preinstalled", false)) &&(!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt", null)))) {// mPreInstallObserver = new AppDirObserver(// mPreinstallAppDir.getPath(), OBSERVER_EVENTS, false);// mPreInstallObserver.startWatching();if (preinstallAppDir.exists()) {// scanDirLI(mPreinstallAppDir, 0, scanMode, 0);copyPackagesToAppInstallDir(preinstallAppDir);}// mPreInstallDelObserver = new AppDirObserver(// mPreinstallAppDelDir.getPath(), OBSERVER_EVENTS, false);// mPreInstallDelObserver.startWatching();if (preinstallAppDelDir.exists()) {copyPackagesToAppInstallDir(preinstallAppDelDir);deletePreinstallDir(preinstallAppDelDir);}SystemProperties.set("persist.sys.preinstalled", "1");}//$_rockchip_$_modify_end

关键函数是copyPackagesToAppInstallDir(),它会把preinstall目录下的安装文件copy到安装目录。
这样安装就成功了。

安装preinstall和preinstall_del的区别在于后者在安装完之后会删除系统目录下的apk,因此要是做了恢复出厂设置或者卸载动作,那就不能恢复了。

删除函数是deletePreinstallDir(),通过init中的ctl命令实现。

    private void deletePreinstallDir(File dir) {String[] files = dir.list();if (files != null) {Slog.d(TAG, "Ready to cleanup preinstall");SystemProperties.set("ctl.start", "preinst_clr");}}

不过在source code中并没有找到preinst_clr这个service,可以在init.rc中自己添加下,
参考的是 Nu3001/device_rockchip_rksdk

service preinst_clr /system/bin/preinstall_cleanup.sh
disabled
oneshot

preinstall_cleanup.sh这个文件默认是有的,本质是直接删除apk。

#!/system/bin/sh
log -t PackageManager "Start to clean up /system/preinstall_del/"
mount -o rw,remount -t ext4 /system
rm system/preinstall_del/*.*
mount -o ro,remount -t ext4 /system

http://www.dtcms.com/a/399719.html

相关文章:

  • wordpress升级php7北京网站优化步
  • Multipath
  • Optuna v4.5新特性深度解析:GPSampler实现约束多目标优化
  • Remote JVM Debug远程给Java程序“做手术”!cpolar内网穿透实验室第626个成功挑战
  • 开发网站 需求做购物网站怎拼找商家
  • OpenAI报告:人们如何使用ChatGPT
  • 做网站需要多少屏山东建设网站广告
  • 高系分十九:大数据处理系统分析与设计
  • STM32H750xx【QSPI】轮询方式读写GD25Q64E
  • 校园网站素材国内搜索引擎排名第一
  • 中国制造网的网络营销方式桔子seo工具
  • wordpress扒站教程网站总体规划说明
  • IP地址管理:部署phpIPAMv1.7.3常见问题
  • 自己做服务器网站表白网站建设
  • 【计算广告】广告出价相关约束问题:PID控制、MPC预测算法
  • 教你如何建设网站网站建设和维护费用
  • kotlin图算法
  • 汕尾网站建设 生意好吗有专门为个人网站做推广的吗
  • 网站建设企业响应式网站模板宿迁城乡住房建设厅网站
  • 建网站需要学什么网站专业术语中SEO的意思是
  • 2025无人机在低空物流中的应用实践
  • Python实现海鸥优化算法(Seagull Optimization Algorithm, SOA)(附完整代码)
  • PostgreSQL 知识体系
  • 网站建设与维护专业实训室昆山做网站的
  • 插针弹簧镀金耐腐蚀、高导电的电子连接“保护盾”|深圳同远
  • 【MySQL✨】MySQL 入门之旅 · 第十一篇:MySQL 表连接(JOIN)基础
  • 德州有做网站的制作表白网站
  • 公司网站做推广成化区建设局网站
  • Openssl TRNG provider demo guide
  • 建立论坛网站做自己的网站不是免费的