一、前言
最近遇到一个需求,需要预置第三方apk至Android 4.4系统里面。预置的apk可以被用户卸载,并且Android系统恢复出厂后,预置的apk又可以自动安装恢复。
思路分析:
- 可以被用户卸载,即需要安装到/data/app目录下。
- 恢复出厂后apk又可以自动安装,则需要将apk存放至系统的某一个目录下,设置一个标志位,刷机或者恢复出厂第一次开机安装这些apk。即采用预安装方式(preinstall)来处理。
二、preinstall集成方法
1. 建立preinstall目录
sdk根目录下输入
mkdir -p vendor/packages/preinstall
2. 创建preinstall.sh脚本
在vendor/packages/preinstall目录下建立preinstall.sh脚本,添加以下代码:
#!/system/bin/sh
MARK=/data/local/symbol_thirdpart_apks_installed
PKGS=/system/preinstall/
if [ ! -e $MARK ]; then
echo "booting the first time, so pre-install some APKs."
busybox find $PKGS -name "*\.apk" -exec sh /system/bin/pm install {} \;
# NO NEED to delete these APKs since we keep a mark under data partition.
# And the mark will be wiped out after doing factory reset, so you can install
# these APKs again if files are still there.
# busybox rm -rf $PKGS
touch $MARK
echo "OK, installation complete."
fi
3. 创建Android.mk文件
在vendor/packages/preinstall目录下建立Android.mk文件,添加以下代码:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := preinstall.sh
LOCAL_SRC_FILES := preinstall.sh
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT)/bin
include $(BUILD_PREBUILT)
manager_apk := $(patsubst $(LOCAL_PATH)/%,%,$(wildcard $(LOCAL_PATH)/*.apk))
$(foreach t,$(manager_apk), \
$(eval include $(CLEAR_VARS)) \
$(eval LOCAL_MODULE := $(notdir $(t))) \
$(eval LOCAL_MODULE_TAGS := optional) \
$(eval LOCAL_MODULE_CLASS := ETC) \
$(eval LOCAL_MODULE_PATH := $(TARGET_OUT)/preinstall) \
$(eval LOCAL_SRC_FILES := $(t)) \
$(eval LOCAL_CERTIFICATE := shared) \
$(eval include $(BUILD_PREBUILT)) \
)
$(LOCAL_INSTALLED_MODULE): $(notdir $(manager_apk))
4. init.rc脚本处理
在init.rc脚本里面添加以下代码:
on property:init.svc.bootanim=stopped
start preinstall
service preinstall /system/bin/preinstall.sh
user root
group root
disabled
oneshot
5. 创建vendor.mk文件
在vendor下创建vendor.mk文件,添加以下代码:
#Third Part App
PRODUCT_PACKAGES += \
preinstall.sh \
$(patsubst $(TOP)/vendor/packages/preinstall/%,%,$(wildcard $(TOP)/vendor/packages/preinstall/*.apk))
6. vendor.mk参与编译
在device.mk中添加
$(call inherit-product, vendor/vendor.mk)
三、其它
1. 注意
- 集成路径随意修改。
- device.mk一般指的是device/xxxx/芯片型号下的mk文件,不同芯片平台名称不同。
- init.rc一般指的是init.xxx.rc,不同芯片平台名称不同。
- 上面将apk存放至/system/preinstall目录下,实际使用时注意system分区的大小。