[RK3288][Android6.0] 调试笔记 --- 系统自带预置第三方APK方法
来源:互联网 发布:淘宝女装店背景图 编辑:程序博客网 时间:2024/05/16 07:29
Platform: RK3288
OS: Android 6.0
Kernel: 3.10.92
Rockchip默认提供了机制来预置第三方APK, 方法很简单:
1. 在device/rockchip/rk3288创建preinstall目录(如果要可卸载,那就创建preinstall_del目录)
2. 将你要预安装的APK放进此目录即可
下面看下实现原理过程:
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.mkendif
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 install makefile_path = preinstall_dir + '/Android.mk' #Use to include modules include_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 := AVSourceTesterLOCAL_MODULE_CLASS := APPSLOCAL_MODULE_PATH := $(TARGET_OUT)/preinstallLOCAL_SRC_FILES := $(LOCAL_MODULE)$(COMMON_ANDROID_PACKAGE_SUFFIX)LOCAL_CERTIFICATE := PRESIGNEDLOCAL_DEX_PREOPT := falseLOCAL_MODULE_TAGS := optionalLOCAL_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/shlog -t PackageManager "Start to clean up /system/preinstall_del/"mount -o rw,remount -t ext4 /systemrm system/preinstall_del/*.*mount -o ro,remount -t ext4 /system
- [RK3288][Android6.0] 调试笔记 --- 系统自带预置第三方APK方法
- [RK3288][Android6.0] 调试笔记 --- 强制第三方apk横屏显示
- [RK3288][Android6.0] 调试笔记 --- /data/app/预置apk安装失败
- [RK3288][Android6.0] 调试笔记 --- 隐藏系统状态栏的方法
- [RK3288][Android6.0] 调试笔记 --- 系统Dump Callstack方法
- [RK3288][Android6.0] 调试笔记 --- 无法安装需系统权限的apk问题
- [RK3288][Android6.0] 调试笔记 --- apk安装添加黑名单
- [RK3288][Android6.0] 调试笔记 --- Launcher中隐藏APK图标
- [RK3288][Android6.0] 调试笔记 --- Ubuntu下重新签名apk方法
- 预置第三方apk
- 预置第三方apk
- [RK3288][Android6.0] 调试笔记 --- 替换系统签名
- [RK3288][Android6.0] 调试笔记 --- 屏蔽系统下拉菜单显示
- [RK3288][Android6.0] 调试笔记 --- 修改系统按键
- [RK3288][Android6.0] 调试笔记 --- 系统识别不同硬件版本方法
- [RK3288][Android6.0] 调试笔记 --- 读取当前DDR频率方法
- [RK3288][Android6.0] 调试笔记 --- USB Camera旋转图像方法
- [RK3288][Android6.0] 调试笔记 --- 屏幕显示旋转方法
- 在Linux上安装Git
- pthread_exit()和return()
- Js实现一个时间显示器
- 助你快速踏入高薪职场——2017面试集锦之java基础(二)
- 解决@Value注解不能为静态变量赋值
- [RK3288][Android6.0] 调试笔记 --- 系统自带预置第三方APK方法
- 关于PLSQL配置了正确的Oracle客户端但是不能识别tnsnames.ora问题
- hashmap 与hashtable区别(学习工厂模式笔记)
- mysq使用问题记录
- caffe运行mnist出现-bash: ./examples/mnist/train_lenet.sh: usr/bin/env: bad interpreter: No such file问题解决
- 指针部分知识
- SSH spring+struts2+hibernate整合步骤
- 【OpenCV入门教程之一】 安装OpenCV:OpenCV 3.0、OpenCV 2.4.8、OpenCV 2.4.9 +VS 开发环境配置
- gcc/g++编译优化