有关Android中预置文件的几种方法

时间:2024-03-11 15:17:28

2021-02-05

关键字:预置第三方APK


 

1、预置带源码的工程

 

1.1、APK

理论上可以在源码任意位置存放你的APK工程,但一般都将它放在 ./vendor/xxx/apps 或 ./packages/apps 目录下。

 

然后再以如下内容创建一个 Android.mk 文件:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# apk的名称 LOCAL_PACKAGE_NAME :
= GPIOAPI LOCAL_SRC_FILES := $(call all-subdir-java-files) \ src/com/unionman/gpioapi/IGPIOManager.aidl LOCAL_MODULE_TAGS := optional LOCAL_CERTIFICATE := platform LOCAL_PROGUARD_ENABLED := disabled ALL_DEFAULT_INSTALLED_MODULES += $(LOCAL_PACKAGE_NAME) include $(BUILD_PACKAGE)

 

1.2、C程序

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := DTUServer
LOCAL_SRC_FILES := \
    DTUServer.c \
    485Listener.c \
    GPIOListener.c \
    messenger.c \
    timer.c \
    parser.c
    
LOCAL_C_INCLUDES := \
    $(LOCAL_PATH)/include

LOCAL_CFLAGS += -DCONFIG_LOG_DEBUG

ALL_DEFAULT_INSTALLED_MODULES += $(LOCAL_MODULE)

include $(BUILD_EXECUTABLE)

 

 

2、预置无源码的APK

 

2.1、预置为普通应用

普通系统应用即与用户自行下载并安装的APK完全一样的,是用户可随意卸载且在卸载后即使是恢复出厂设置也不能恢复的应用。这种应用恢复出厂设置操作不仅不会恢复已卸载的应用,还会将没有卸载的应用也一并清理掉。

 

预置这种应用有三种 Android.mk 编写方式:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := TsBrowser
LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)

LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
LOCAL_CERTIFICATE := PRESIGNED

ALL_DEFAULT_INSTALLED_MODULES += $(LOCAL_MODULE)

include $(BUILD_PREBUILT)

这种方式的关键在 ALL_DEFAULT_INSTALLED_MODULES ,这一句使得在编译大包时能够将这个应用打包进系统镜像中去。

 

第二种方式的 Android.mk 编写方式如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := TsBrowser
LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)

LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
LOCAL_CERTIFICATE := PRESIGNED

include $(BUILD_PREBUILT)

与第一种方式相比,少了 ALL_DEFAULT_INSTALLED_MODULES 语句。但是这种方式必须要在 ./device/<manufactor>/<product>/device.mk 文件中添加如下语句:

PRODUCT_PACKAGES += TsBrowser

只有添加了这条语句才能让你预置的应用在编译大包时一并打包进系统镜像中去。

 

最后一种方式其实只有两句话,它是直接利用 cp 命令来将要预置的应用拷贝到 out 目录指定位置下以待打包进系统镜像中的:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

$(shell mkdir -p $(TARGET_OUT_DATA_APPS) ) #直接利用拷贝命令来预置 $(shell
cp -af $(LOCAL_PATH)/TsBrowser.apk $(TARGET_OUT_DATA_APPS))

 

 

2.2、预置为普通系统应用

系统应用,用户不可卸载,安装位置为 /system/app 。

 

其 Android.mk 内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := TsBrowser
LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)

LOCAL_PREBUILT_JNI_LIBS:= \
@lib/armeabi-v7a/libAnalyzeData.so     \
@lib/armeabi-v7a/libAudioEngine.so     \
...
@lib/armeabi-v7a/libWndVideos.so


LOCAL_CERTIFICATE := PRESIGNED
LOCAL_MODULE_PATH := $(TARGET_OUT_APPS) ALL_DEFAULT_INSTALLED_MODULES
+= $(LOCAL_MODULE) include $(BUILD_PREBUILT)

上面的 LOCAL_PREBUILT_JNI_LIBS 所描述的就是 APK 中的 so 库的名称。使用这种方式预置APK时,要先将APK中的所有库文件提取出来以待编译时自动预置这些库文件。否则的话可能导致运行APK时报找不到对应的动态库错误。

 

当然,这里同样可以直接在编译时使用 cp 命令来将 APK 拷贝至编译结果 out 目录下的 /system/app 目录下,其 Android.mk 内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

$(shell mkdir -p $(TARGET_OUT)/app )

#利用拷贝命令来预置
$(shell cp -af $(LOCAL_PATH)/TsBrowser.apk $(TARGET_OUT)/app)

使用这种直接拷贝的方式时应主动为 APK 签个名,否则可能会有无法安装的问题。同样也得将所有的动态库拷贝至 /system/lib 目录下。

 

2.3、预置为私有系统应用

私有系统应用即安装目录为 /system/priv-app 的应用,这些应用在 Android 系统中作为等级最高的应用。 /system/app 下的应用仍能在设置--应用中看到安装信息,但 /system/priv-app 下的则无法在常规应用中查看到它们的信息。

 

不过预置这种形式的应用与预置普通系统应用的基本一致,所不同的就是它多了一条 mk 语句:

LOCAL_PRIVILEGED_MODULE := true

 

 

3、预置普通文件

直接在编译时通过 cp 命令拷贝至你希望它存在的目录就可以了,任何文件都可以以这种方式来预置。

LOCAL_PATH := $(call my-dir)

# ----------------------- script ---------------------------#
include $(CLEAR_VARS)
UM_FILES_PATH = $(LOCAL_PATH)/script
UM_OUT = $(TARGET_OUT)/bin

$(shell mkdir -p $(UM_OUT) )

define find_script_files
$(shell find $(1) -type f -name "*.sh" -exec cp {} $(UM_OUT) \;)
endef

$(call find_script_files, $(UM_FILES_PATH) )

$(shell cp -af $(LOCAL_PATH)/xxx/my_file.file $(TARGET_OUT))

# -----------------------

 

4、循环拷贝预置文件

 

在编译大包时将指定目录下的所有指定类型文件预置进系统镜像中,请直接参阅笔者的另一篇文章:

Android.mk中利用循环拷贝所有文件