# 使用 Android Studio 开发系统 App 站点:答源(https://www.dandroid.cn/) 原文:https://www.dandroid.cn/archives/20512 Canonical:https://www.dandroid.cn/archives/20512 作者:admin 发布日期:2023-09-15 最后更新:2023-09-15 17:25 分类:Android系统开发 / Framework源码 内容类型:post 说明:本页是原文的纯文本镜像,供大模型与检索器完整读取;不含导航、广告、付费框。引用请以上方「原文」链接为准。 ## 正文 本文基于 AOSP Android10_r41 源码环境。 1. 编译 framework 模块 系统应用可以调用隐藏的API,这需要我们引入包含被隐藏 API 的 jar 包。 为了得到这个 jar 包,我们需要在源码下编译 Framework 模块: source lunch rice14-eng # Android10 及以前 make framework # Android11 及以后 #make framework-minus-apex 编译完成后,我们在 out/target/common/obj/JAVA_LIBRARIES/framework_intermediates 目录下找到 classes.jar 文件,为方便识别,我们将该文件拷贝到其他地方,并将文件名修改为 framework.jar 。 2. 创建系统 App 项目 使用 Android Studio 创建一个 Empty Activity 空项目。接着把之前准备好的 framework.jar 拷贝到项目的 app/libs 文件夹中。 接着修改项目根目录下的 build.gradle,添加如下内容: allprojects{ gradle.projectsEvaluated { tasks.withType(JavaCompile) { Set fileSet = options.bootstrapClasspath.getFiles() List newFileList = new ArrayList<>(); newFileList.add(new File("./app/framework/framework.jar")) newFileList.addAll(fileSet) options.bootstrapClasspath = files( newFileList.toArray() ) } } } 接着修改 app/build.gradle: dependencies { compileOnly files('libs/framework.jar') //....... } 然后在项目的 AndroidManifest.xml 中添加: 接着我们需要制作系统签名,这里使用 keytool-importkeypair 签名工具。 将 keytool-importkeypair clone 到本地,并将其中的 keytool-importkeypair 文件添加到 PATH 路径。 接着进入系统源码下的 build/target/product/security 路径,接着执行: keytool-importkeypair -k ./platform.keystore -p android -pk8 platform.pk8 -cert platform.x509.pem -alias platform k 表示要生成的签名文件的名字,这里命名为 platform.keystore -p 表示要生成的 keystore 的密码,这里是 android -pk8 表示要导入的 platform.pk8 文件 -cert 表示要导入的platform.x509.pem -alias 表示给生成的 platform.keystore 取一个别名,这是命名为 platform 接着,把生成的签名文件 platform.keystore 拷贝到 Android Studio 项目的 app 目录下,然后在 app/build.gradle 中添加签名的配置信息: android { signingConfigs { sign { storeFile file('platform.keystore') storePassword 'android' keyAlias = 'platform' keyPassword 'android' } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' signingConfig signingConfigs.sign } debug { minifyEnabled false signingConfig signingConfigs.sign } } } 至此,我们在 AS 中就搭建好了我们的系统 App 3. 系统 APP 的编译运行 在开发过程中,大部分情况下,我们可以直接点击 Android Stuido 中的运行按钮来运行我们的配置好的 App。当我们的 App 开发完成,我们需要将其预制到系统中: 我们在系统源码下的 device/Jelly/Rice14 目录下,创建如下的文件与文件夹: AsSystemApp ├── Android.mk └── app.apk 其中 app.apk 是我们用 Android Studio 打包好的 apk 安装包。Android.mk 的内容如下(Android10 下,Android.bp 貌似还不支持引入 apk,实测 Android13 是没问题的,这里就使用 Android.mk 了): LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_MODULE := AsSystemApp LOCAL_CERTIFICATE := PRESIGNED LOCAL_SRC_FILES := app.apk LOCAL_MODULE_CLASS := APPS LOCAL_PRODUCT_MODULE := true include $(BUILD_PREBUILT) 接着修改 device/Jelly/Rice14/Rice14.mk PRODUCT_PACKAGES += \ AsSystemApp 然后编译系统,启动虚拟机,就可以看到我们的 App 了。 source build/envsetup.sh lunch Rice14-eng make -j16 emulator 4. 系统 App 特点 4.1 系统 app 可以执行三方 App 不能执行的 Api 一些 API 只能又系统 App 调用,比如: SystemClock.setCurrentTimeMillis(0) 如果在普通 App 中使用,就会报以下的错误: E/SystemClock: Unable to set RTC java.lang.SecurityException: setTime: Neither user 10099 nor current process has android.permission.SET_TIME. 网络上很多文章教你在 App 如何调用 Hide 的 Api,在系统 App 中可以直接使用这些 Hide Api: import android.os.SystemClock class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) SystemClock.setCurrentTimeMillis(0) intent = Intent(this, TestService::class.java) startService(intent) //在系统 App 中可以正常使用 //AudioSystem 整个类被标记为 hide Log.d("MainActivity", "" + AudioSystem.STREAM_ACCESSIBILITY) } } 4.2 进程保活 为了保活,开发者不知道加了多少班,掉了多少头发。在系统 App 这里,可以说保活不要太简单了: 在 AndroidManifest.xml 中添加: 最后直接点击运行按钮启动我们的 App,可以看到 Service 一直再打 Log。 我们使用 ps -ef | grep "AsSystemApp" 查找到我们 App 对应的 pid,然后使用 kill 命令将其强杀掉,经过短暂的等待后,Log 窗口又开始打 Log 了,说明我们的 App 在强杀后,被系统重新拉起运行。 4.3 系统 App 权限 相比三方 App,系统 App 可以使用更多的权限。因为这部分内容涉及较多系统权限相关的基础知识。我们就在系统权限部分再来讲解系统 App 权限相关的内容吧。 --- 由 答源 DAN 底座 1.4.1 生成 · 2026-11-12T19:11:08+00:00