Android Framework 常见解决方案(15)android内置可卸载APP集成方案

1 原理

在Android源码中添加一个可卸载APP的普通应用(该应用是 需要一个用于集成的apk文件、至于Android.mk文件可以有但非必要),和系统级应用集成不同的是LOCAL_CERTIFICATE变量值的不同,系统级应用对应的是platform,而普通可卸载应用对应的是testkey(注意:应用输出的路径要改变),但仅仅如此还不够。因为普通应用不是直接拷贝到 /data/app 目录下就可以的,还是需要安装这一步骤的。

这里使用一个新思路,将普通应用安装包放到system分区下,开机后启动一个脚本程序preload_app.sh,在系统启动后(注意:如果开机就执行pm的 安装命令是启动不了的,因为还未彻底初试化完毕)执行如下逻辑:

  1. 如果是第一次开机或 将恢复出厂设置/升级,则安装该应用。
  2. 如果不是第一次开机,则不安装该用。

这样就确保即使恢复了出厂设置应用还在,同时保证安装应用后可以被自由卸载/升级。

2 修改方案(Android O P Q)

2.1 添加第三方应用apk文件

在${AOSP}/package/apps/路径下 添加一个普通可卸载应用Taobao.,添加对应的Android.mk文件,如下所示:

LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := Taobao.apk
LOCAL_MODULE_CLASS := APPS
#可以为user、eng、tests、optional,optional代表在任何版本下都编译
LOCAL_MODULE_TAGS := optional
#编译模块的名称
LOCAL_MODULE := Taobao
#可以为testkey、platform、shared、media、PRESIGNED(使用原签名),platform代表为系统应用
LOCAL_CERTIFICATE := testkey
#应用输出路径,此处为data/app
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
#module的后缀,可不设置
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_DEX_PREOPT := false #不进行预先优化,一般第三方应用会避免优化,而导致APP各种异常
include $(BUILD_PREBUILT)

接下来在该目录下 添加对应的 package/apps/Taobao/Taobao.apk文件。这样该目录就完成了编辑。

然后我们再修改下系统的配置文件(根据项目的实际需求,这里仅采用一种通用的方式供参考)同时修改文件

build/make/target/product/sdk_base.mk
build/make/target/product/generic_no_telephony.mk

给PRODUCT_PACKAGES 环境变量 添加新任务,如下所示:

@@ -49,7 +49,8 @@ PRODUCT_PACKAGES := \
     EasterEgg \
     WallpaperPicker \
     WidgetPreview \
+    Taobao \

2.2 在framework层添加preload_app.sh

添加文件为{AOSP}/frameworks/base/data/cmds/preload_app/目录,在该目录下添加文件

preload_app.sh,内容为:

#!/system/bin/sh
if [ ! -f /data/app/did ]; then
    PRELOAD_SOURCE=/system/preload-app
    files=$(ls ${PRELOAD_SOURCE}/)
    for i in ${files};do
        #pm install -g ${PRELOAD_SOURCE}/${i}
        pm install ${PRELOAD_SOURCE}/${i}
        #chmod 755 ${PRELOAD_DEST}/${i}
    done
    echo 1 > /data/app/did
fi

同时添加Android.mk文件,内容如下:

# Copyright 2013 The Android Open Source Project
#
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := preload_app.sh
LOCAL_SRC_FILES := preload_app.sh
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE_TAGS := optional
include $(BUILD_PREBUILT)   

同时配置关键环境变量如下(这里仅给出参考的关键变量,一般是在aosp/device/目录下添加):

PRODUCT_PACKAGES += \
    preload_app.sh
PRODUCT_COPY_FILES += \
    frameworks/base/cmds/preload_app/preload_app.sh:$(TARGET_COPY_OUT_SYSTEM)/bin/preload_app.sh  \
#针对要拷贝的apk,需要添加
PRODUCT_COPY_FILES += \
    packages/apps/X1/X1.apk:$(TARGET_COPY_OUT_SYSTEM)/preload-app/X1.apk \
    packages/apps/X2/X2.apk:$(TARGET_COPY_OUT_SYSTEM)/preload-app/X2.apk \
    //...
    packages/apps/XN/XN.apk:$(TARGET_COPY_OUT_SYSTEM)/preload-app/XN.apk \

2.3 配置SELinux

修改文件 device/qcom/sepolicy/generic/private/file_contexts,内容添加如下:

/system/bin/preload_app.sh       u:object_r:preload_app_exec:s0

添加文件 device/qcom/sepolicy/generic/private/preload_app.te,内容添加如下:

#preload_app_copy_exec
type preload_app, domain;
type preload_app_exec, system_file_type, exec_type, file_type;
#init_domain(preload_app)
allow preload_app app_data_file:file{ read write getattr };

2.4 开机启动服务相关修改

修改对应的init.rc文件,同时在系统启动完成后添加如下内容:

#property start
on property:sys.boot_completed=1
    start preload_app

#add bin of shell script
service preload_app /system/bin/preload_app.sh
    class main
    user root
    group root
    seclabel u:r:preload_app:s0
    disabled
    oneshot

主要是确保启动后可以根据需要来设置属性,进而启动该脚本。

你可能感兴趣的:(常见解决方案,framework,android,android,java,apache)