Android 系统预置 APP 是做 Framework 应用开发经常经常会遇到的工作,预置 APP 分为两种,一种是直接预置 APK,一种是预置带有源码的 APP。

预置 apk

示例说明

以 Shadowsocks.apk 示例,在 AOSP/packages/apps 新建名为 Shadowsocks 的文件,放入 Shadowsocks.apk,再新建 Android.mk,内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_MODULE := < your app folder name >

# 签名

LOCAL_CERTIFICATE := < desired key >

# 指定 src 目录

LOCAL_SRC_FILES := < app apk filename >

LOCAL_MODULE_CLASS := APPS

# 该模块的后缀,不用定义

#LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)

include $(BUILD_PREBUILT)

解释:

LOCAL_PATH := $(call my-dir)

每个 Android.mk 文件必须以定义 LOCAL_PATH 为开始,它用于在开发 tree 中查找源文件。

include $(CLEAR_VARS)

CLEAR_VARS 变量由 Build System 提供,并指向一个指定的 GNU Makefile,由它负责清理很多 LOCAL_xxx。

例如:LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES 等等,但不清理 LOCAL_PATH。

LOCAL_MODULE_TAGS := user eng tests optional

可选定义,表示在什么版本情况下编译该版本,默认 optional

user: 指该模块只在 user 版本下才编译

eng: 指该模块只在 eng 版本下才编译

tests: 指该模块只在 tests 版本下才编译

optional:指该模块在所有版本下都编译

LOCAL_MODULE

模块名,可不用定义,默认 = $(LOCAL_PACKAGE_NAME),不能和既有模块相同,如果该变量未设置,则使用 LOCAL_PACKAGE_NAME,如果再没有,就会编译失败。

LOCAL_CERTIFICATE

在什么情况下签名。

testkey:普通 APK,默认情况下使用。

platform:该 APK 完成一些系统的核心功能。经过对系统中存在的文件夹的访问测试,

这种方式编译出来的 APK 所在进程的 UID 为 system,可以参见 Settings。

shared:该 APK 需要和 home/contacts 进程共享数据,可以参见 Launcher。

media:该 APK 是 media/download 系统中的一环,可以参见 Gallery。

LOCAL_MODULE_CLASS

指定模块的类型,可不用定义。

# 编译 apk 文件

LOCAL_MODULE_CLASS := APPS

# 编译 jar 包

LOCAL_MODULE_CLASS := JAVA_LIBRAYIES

# 定义动态库文件

LOCAL_MODULE_CLASS := SHARED_LIBRAYIES

# 编译可执行文件

LOCAL_MODULE_CLASS := EXECUTABLES

include $(BUILD_PACKAGE)

表示生成一个 apk,它可以是多种类型

BUILD_PACKAGE(既可以编apk,也可以编资源包文件,但是需要指定LOCAL_EXPORT_PACKAGE_RESOURCES:=true)

BUILD_JAVA_LIBRARY(java共享库)

BUILD_STATIC_JAVA_LIBRARY(java静态库)

BUILD_EXECUTABLE(执行文件)

BUILD_SHARED_LIBRARY(native共享库)

BUILD_STATIC_LIBRARY(native静态库)

完整示例

Shadowsocks.apk 对应如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_MODULE := Shadowsocks

# 系统签名

LOCAL_CERTIFICATE := PRESIGNED

LOCAL_SRC_FILES := $(LOCAL_MODULE).apk

LOCAL_MODULE_CLASS := APPS

#LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)

include $(BUILD_PREBUILT)

更改 device.mk 文件

AOSP/build/target/board/lunch的版本/device.mk 文件,我编的是 aosp_x86-eng,所以增加或者更新 AOSP/build/target/board/generic_x86/device.mk:

PRODUCT_PACKAGES += \

Shadowsocks \

使用 mmm 命令来编译指定的模块:

mmm packages/apps/Shadowsocks

编译好模块后,还要重新打包一下 system.img 文件:

make snod

完成后就可以烧录了。

问题

1、如何将 APK 预置到 system/priv-app 里?

加入 priv-app 方法:在 Android.mk 中增加 LOCAL_PRIVILEGED_MODULE := true

预置有源码 APP

预置有源码 APP 比预置 APK 要麻烦很多,可能会涉及 jar 包和 so 库等。现在基本都是基于 Android Studio 的项目 MyTestProject1,我们先在 AOSP/packages/apps 新建名为 MyTestProject2 的文件夹,在新建 MyTestProject2/libs、MyTestProject2/res、MyTestProject2/src,分别将 MyTestProject1 下 jar 包和 so 库拷到 MyTestProject2/libs 和 MyTestProject2/libs/armeabi,将 MyTestProject1/app/src/main/res 拷到 MyTestProject2/res,将 MyTestProject1/app/src/main/java 下文件拷到 MyTestProject2/src 下。

引用第三方 jar 包

假设,我们当前目录下的 libs 有 AndroidUtil.jar包,我们想引用它,需要做两个步骤:

第一步、 声明我们 jar 包所在的目录

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := AndroidUtil:libs/AndroidUtil.jar

这行代码的意思大概可以理解成这样,声明一个变量 AndroidUtil,它的 value 是 libs/AndroidUtil.jar

include $(CLEAR_VARS)

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := AndroidUtil:libs/AndroidUtil.jar

include $(BUILD_MULTI_PREBUILT)

第二步、 引用我们声明 jar 包的变量

include $(CLEAR_VARS)

# 省略其他

LOCAL_STATIC_JAVA_LIBRARIES := \

AndroidUtil

# 省略其他

include $(BUILD_PACKAGE)

引用 so 库

假设,我们当前目录下的 libs/armeabi 有 libBaiduMapSDK1.so、libBaiduMapSDK1.so,libs/arm64-v8a 有 libBaiduMapSDK1.so、libBaiduMapSDK1.so,我们想引用它,有两种方法,可以在根目录 Android.mk 引用 so 库,也可以在 libs 下再建个 Android.mk 配置好 so 库,然后 include,推荐第二种方式。

libs/Android.mk

#====================================================

include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_MODULE_SUFFIX := .so

LOCAL_MODULE := libBaiduMapSDK1

LOCAL_MODULE_CLASS := SHARED_LIBRARIES

LOCAL_SRC_FILES_arm :=libs/armeabi/$(LOCAL_MODULE).so

LOCAL_SRC_FILES_arm64 :=libs/arm64-v8a/$(LOCAL_MODULE).so

LOCAL_MODULE_TARGET_ARCHS:= arm arm64

LOCAL_MULTILIB := both

include $(BUILD_PREBUILT)

#====================================================

#====================================================

include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_MODULE_SUFFIX := .so

LOCAL_MODULE := libBaiduMapSDK2

LOCAL_MODULE_CLASS := SHARED_LIBRARIES

LOCAL_SRC_FILES_arm :=libs/armeabi/$(LOCAL_MODULE).so

LOCAL_SRC_FILES_arm64 :=libs/arm64-v8a/$(LOCAL_MODULE).so

LOCAL_MODULE_TARGET_ARCHS:= arm arm64

LOCAL_MULTILIB := both

include $(BUILD_PREBUILT)

引用 so 库

include $(CLEAR_VARS)

# 省略其他

LOCAL_JNI_SHARED_LIBRARIES := \

libBaiduMapSDK1 \

libBaiduMapSDK2

# 省略其他

include $(BUILD_PACKAGE)

##########引用第三方 so 库##########

include $(LOCAL_PATH)/libs/Android.mk

完整示例

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_PACKAGE_NAME := TestName

LOCAL_CERTIFICATE := platform

# 引入系统资源文件

LOCAL_USE_AAPT2 := true

# Java文件

LOCAL_SRC_FILES := $(call all-java-files-under, src)

# 资源文件,可选定义,推荐不定义

#LOCAL_RESOURCE_DIR = \

# $(LOCAL_PATH)/res \

# frameworks/support/v7/appcompat/res \

# frameworks/support/design/res

# 可以使用系统 hide api

LOCAL_PRIVATE_PLATFORM_APIS := true

# 导入系统依赖

LOCAL_STATIC_ANDROID_LIBRARIES := \

android-support-design \

android-support-v4 \

android-support-v7-appcompat \

android-support-v7-recyclerview

LOCAL_STATIC_JAVA_LIBRARIES := \

AndroidUtil

LOCAL_JNI_SHARED_LIBRARIES := \

libBaiduMapSDK1 \

libBaiduMapSDK2

# R资源生成别名,--extra-packages 是为资源文件设置别名:意思是通过该应用包名+R,com.android.test1.R 和 com.android.test2.R 都可以访问到资源

LOCAL_AAPT_FLAGS := --auto-add-overlay

LOCAL_AAPT_FLAGS += --extra-packages android.support.v4

LOCAL_AAPT_FLAGS += --extra-packages android.support.v7.appcompat

LOCAL_AAPT_FLAGS += --extra-packages android.support.design

LOCAL_AAPT_FLAGS += --extra-packages android.support.v7.recyclerview

# 制定编译的工程,不要使用代码混淆的工具进行代码混淆

LOCAL_PROGUARD_ENABLED := disabled

# 指定不需要混淆的native方法与变量的proguard.flags文件

LOCAL_PROGUARD_FLAG_FILES := proguard.flags

include $(BUILD_PACKAGE)

##########引用第三方 jar 包##########

include $(CLEAR_VARS)

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := AndroidUtil:libs/AndroidUtil.jar

include $(BUILD_MULTI_PREBUILT)

##########引用第三方 so 库##########

include $(LOCAL_PATH)/libs/Android.mk

问题

1、LOCAL_PRIVATE_PLATFORM_APIS 和 LOCAL_SDK_VERSION 有什么区别?

LOCAL_PRIVATE_PLATFORM_APIS := true

设置后,会使用 sdk 的 hide 的 api 来编译。

LOCAL_SDK_VERSION 这个编译配置,就会使编译的应用不能访问 hide 的 api,有时一些系统的 class 被 import 后编译时说找不到这个类,就是这个原因造成的。

2、如果直接用 mmm 编译然后 adb install -r xxx.apk 大概会出现如下错误:

Failed to install out/target/product/p212/system/app/xxx/xxx.apk: Failure [INSTALL_FAILED_INVALID_APK: Package couldn't be installed in /data/app/com.droidlogic.mboxlauncher-1: Package /data/app/com.droidlogic.mboxlauncher-1/base.apk code is missing]

解决方法:

在对应 app 的 Android.mk 文件中加入

LOCAL_DEX_PREOPT := false

关闭 dex 优化来提高调试过程,把编译后的 APK 直接替换安装 adb install -r XXX.apk,不然 APK 得 Push 到 system/app,重启设备。

3、在 Android Studio Gradle 方式中通过 implementation 方式加载的三方库,并没有下载 jar 文件放到 libs 文件夹下啊,该如何集成?

其实 jar 包有被下载到项目的 External Libraries 目录下,找到引用的 jar 包,点右键 Show in Files,就能得到了 jar 包的文件地址,然后把它拷到 libs 文件夹下,就能像别的 jar 包一样处理了。

另外在 External Libraries 目录还能看到隐藏的 jar,比如 retrofit,其实它有引用 okhttp,okhttp 又引用了 okio,这些也是需要的,一并拷到 libs 文件夹下。

4、第三方无法定位?

第三方定位如百度、高德,申请 SDK 时会需要填写包名和打包签名等信息,如何正确地预置源码 APP 可以定位,除了配置LOCAL_CERTIFICATE := platform使用系统的签名,还得在项目的AndroidMainfest.xml 根节点配置android:sharedUserId="android.uid.system"。

公众号

我的公众号:吴小龙同学,欢迎关注交流,公众号回复关键字「1024」有惊喜。

android 预置 app,AOSP 预置 APP相关推荐

  1. Android系统静默安装预置应用宝

    Android系统预置应用宝 如果直接按照常规方案预置应用宝到system/app下的话,会报好多Selinux错误,导致应用闪退 而应用宝又申请了好多并不需要的权限例如su 本来的方案是第一次开机时 ...

  2. Android 4.3 隐藏功能 App Ops 分析

    原帖位置:http://blog.mssun.me/security/android-4-3-app-ops-analysis/ Android 4.3 刚刚发布,大家还在关心功能上有没有什么亮点的时 ...

  3. Android 关于::app:clean :app:preBuild UP-TO-DATE :app:preDebugBuild UP-TO-DATE,引用jar冲突问题...

    错误提示:  Information:Gradle tasks [:app:clean, :app:generateDebugSources, :app:generateDebugAndroidTes ...

  4. 简单Android手机APP地图,android最简单手机地图APP(只需5分钟)

    android最简单手机地图APP--只有三部分. 第一部分 首先建立一个MapActivity在setContentView(R.layout.activity_map);中创建一个代码如下. [h ...

  5. Android之ActivityManagerService详解(APP启动过程)

    转载请标明出处:[顾林海的博客] 前言 AMS(ActivityManagerService)的启动是在SystemServer进程中启动的,它的职责是用于和所有APP的四大组件进行通信,Activi ...

  6. Android: Execution failed for task ':app:processDebugResources' 异常解决

    Android: Execution failed for task ':app:processDebugResources' 解决: sudo apt-get install -y lib32gcc ...

  7. 【Android学习笔记】设置App启动页

    先将启动页放到项目资源中,图片一般是1080*1920的jpg. 新建一个activity,如图: 创建成功之后,打开刚刚创建的activity,来进行代码的编写: public class BZLa ...

  8. android启动程序唤起其它app,安卓和rn唤起其他app应用

    对于app来说,很多时候都需要在本app中唤起其他app应用,本文简单的列举了安卓和react-native对于唤起其他app的一些做法. 安卓 1)url scheme唤起 使用场景: h5页面跳转 ...

  9. 安卓开发日记(1) - 安装 Android 开发环境和 first app

    安装 Android 开发环境 安装 Android Studio 并升级到最新版本(本文使用 1.0.2 版本) 如果没有安装JDK, 安装 64-bit JDK MAC 下需要手动装一下HAXAM ...

最新文章

  1. golang string 字符串 大小写转换
  2. ActiveMQ(为什么要使用消息中间件,JMS传输模型)
  3. 评分卡建模—拒绝推断
  4. Oracle关于java.sql.SQLException常见错误集锦
  5. Python 日常练习1
  6. 【转】WPF从我炫系列4---装饰控件的用法
  7. CentOS 7 Graylog安装
  8. matlab subplot(figure)如何设置使得图像最终显示出来不一样大小
  9. word 编辑域中的汉字_神器!10秒在word中编辑复杂数学公式,不用mathtype也行!...
  10. 计算机VB圆的面积周长,使用VB设计一个简单的小程序计算圆的面积
  11. 这是一封摘抄的情书有点长你读不完也没关系
  12. bios卡+型号+hp服务器,HPE Gen9 server UEFI BIOS下升级BIOS 阵列卡 HBA卡固件的操作方法...
  13. 5.小程序的Ajax数据请求
  14. Pomelo MMORPG
  15. python定义一个triangle类_Python定义一个三角形类Python学习阶段综合练习2,python,triangle,二...
  16. 计算机的硬盘消失,电脑硬盘突然消失不见
  17. 易企秀把作品转赠给别人,让别人可以编辑
  18. 三极管的缺点MOS管来补,把MOS管当作开关驱动大功率器件
  19. 游戏引擎与游戏开发入门介绍
  20. text-decoration 属性的简单介绍

热门文章

  1. 是什么阻碍了自己写博客
  2. 英语练习137 If I were millionaire
  3. 长垣四中计算机专业有音乐课吗,校园暴力证实为长垣县孟岗四中宿舍内
  4. android系统添加关机铃声
  5. 5G To B是电信“大力丸“?
  6. RabbitMQ的六种工作模式
  7. ARM LINUX 移植c++进程间通信框架RCF2.2
  8. RK3568 替换默认输入法为Pinyin输入法
  9. c++中 和 ||的运算顺序及次数
  10. [CocosCreator]扑克翻牌效果