
1. 项目概述为OpenHarmony设备定义“开机即用”的体验当我们拿到一块全新的开发板刷入最新的OpenHarmony系统开机后第一件事往往是寻找浏览器、设置或文件管理器。如果每次都需要手动从应用市场下载对于批量生产的终端设备或追求极致用户体验的产品来说这显然不够“优雅”。这个项目的核心就是解决这个“最后一公里”的问题如何将我们开发或指定的应用深度集成到OpenHarmony系统中使其成为系统镜像的一部分在设备首次启动时就已预装甚至成为特定文件类型或协议的默认打开程序。今天我将以触觉智能的RK3566开发板为硬件平台基于OpenHarmony 4.1 Release版本带你完整走通“添加默认应用”的全流程。这不仅仅是执行几条命令更重要的是理解OpenHarmony构建系统HarmonyOS Build System 简称HBS的应用集成机制、签名校验逻辑以及系统分区的规划。无论是为自家的智能终端预装专属APP还是进行系统级的定制开发这套方法论都至关重要。2. 核心原理与系统构建流程拆解在动手之前我们必须先跳出“安装应用”的简单思维从OpenHarmony的系统构建层面来理解问题。OpenHarmony的镜像构建是一个高度模块化和自动化的过程应用作为系统的一部分其集成方式决定了它的“身份”。2.1 系统应用 vs 预制应用权限与集成的本质区别很多人会混淆这两个概念但在OpenHarmony的构建体系中它们有明确的界限。系统应用System Application 这类应用通常位于/system/app/目录下拥有较高的系统权限system_basic或system_core级别可以访问受保护的API和资源。它们往往是系统核心功能的组成部分如设置、系统UI、电话等。系统应用需要随系统镜像一起编译其代码和资源直接嵌入到系统分区中。预制应用Preinstalled Application 这才是我们本次操作的主要目标。预制应用通常位于/system/app/或/vendor/app/目录具体取决于产品定义权限级别一般为normal。它们的特点是作为独立的HAPHarmony Ability Package包在系统构建阶段被拷贝到指定目录并完成安装信息的注册。设备出厂后这些应用就已存在用户无需手动安装但一般也无法直接卸载除非有特殊权限。我们的目标就是将第三方应用以“预制应用”的身份集成进去。2.2 OpenHarmony构建系统中的应用集成点OpenHarmony的构建系统通过bundle.json和BUILD.gn文件来管理组件。要预制一个应用关键是要在正确的层级和模块中声明它。产品级配置productdefine在//vendor/[厂商名]/[产品名]/目录下config.json文件定义了本产品包含哪些子系统如applications子系统和特性。这是决定“产品包含什么”的顶层文件。特性配置features在//vendor/[厂商名]/[产品名]/features/目录下.json文件用于声明要激活的特定功能模块。预制应用通常作为一个“特性”被引入。应用编译入口BUILD.gn在应用本身的源码目录或预置配置目录中BUILD.gn文件指导构建系统如何编译、打包以及将HAP输出到哪个分区镜像中。我们的工作就是在这三个环节建立正确的连接告诉构建系统“在构建rk3566产品的system镜像时请把MyApp.hap这个包放进去并处理好它的安装信息。”2.3 签名与权限安全模型的基石OpenHarmony对所有应用都有严格的签名校验机制。预制应用也不例外。应用签名每个HAP包都必须使用开发者证书进行签名。对于预制应用通常使用厂商的私钥证书进行签名而不是调试证书。这确保了应用的来源可信并且其定义的权限请求是经过厂商审核的。权限申请应用在module.json5中声明的权限requestPermissions必须与其签名证书的权限配置文件相匹配。系统在预置时会对这些权限进行校验。如果应用申请了system_api级别的权限但签名证书未被授权则预置会失败。注意在开发调试阶段你可以暂时使用调试证书来快速验证流程。但用于最终量产固件时务必替换为你们公司正式的发布证书否则会带来严重的安全风险。3. 实操准备环境、代码与规划3.1 开发环境与代码准备基础环境确保你的Ubuntu服务器或虚拟机已按照官方文档完成OpenHarmony 4.1 Release版本的基础编译环境搭建包括Python、Node.js、hb工具等。获取源码使用repo工具拉取完整的OpenHarmony 4.1 Release代码。确保//vendor/hihope/触觉智能的厂商代码目录存在。如果不存在可能需要单独获取该厂商适配代码包。确定产品目录本例中我们针对触觉智能RK3566开发板。其产品定义路径通常为//vendor/hihope/rk3566/。请进入该目录查看其结构确认config.json和features目录。3.2 应用准备获取或编译目标HAP包你需要一个准备预制的应用HAP包。有两种方式方式一使用现有应用。例如你可以编译一个简单的“Hello World”应用或者使用OpenHarmony样例应用如//applications/sample/camera/。# 假设在应用源码目录 hb build编译成功后在//out/rk3566/package/phone/目录下具体路径可能因产品而异找到对应的HAP文件如com.example.myapp.hap。方式二准备第三方HAP。如果你有一个已开发好的应用HAP包确保它已使用正确的证书签名并知晓其bundleName包名如com.xxx.myapp。关键检查点记录下这个HAP包的完整包名bundleName和模块名moduleName它们定义在应用的module.json5文件中后续配置将严格依赖这些信息。3.3 规划集成路径放在哪里我们需要决定将应用HAP包和其配置文件放在源码树的哪个位置。一个清晰、规范的存放位置利于维护。常见的做法是在产品目录下创建一个独立的prebuilt-apps目录。我建议的路径结构如下//vendor/hihope/rk3566/ ├── config.json ├── features/ └── prebuilt-apps/ # 新建目录用于存放所有预制应用 └── MyApp/ # 以应用名命名的目录 ├── BUILD.gn # 该应用的构建脚本 ├── MyApp.hap # 应用HAP包可来自编译产出或第三方 └── config.json # 可选该应用的独立特性配置文件4. 分步实现将应用嵌入系统构建链现在我们开始进行具体的配置。请跟随步骤并理解每一步的意图。4.1 步骤一创建应用预置构建脚本在//vendor/hihope/rk3566/prebuilt-apps/MyApp/目录下创建BUILD.gn文件。# //vendor/hihope/rk3566/prebuilt-apps/MyApp/BUILD.gn import(//build/ohos.gni) # 声明一个ohos_prebuilt_hap模板的实例 ohos_prebuilt_hap(myapp_hap) { # 模块名可自定义但在本BUILD.gn文件中需唯一 module_name myapp_hap # 要预制的HAP包源路径相对于本BUILD.gn文件 source ./MyApp.hap # 安装到系统分区后的路径。 # subsystem_name: 所属子系统预制应用通常放在applications子系统。 # part_name: 部件名可以自定义但建议与功能相关如prebuilt_apps。 # 最终安装路径为 /system/app/{part_name}/{module_name}/ install_enable true subsystem_name applications part_name prebuilt_apps # 签名配置。默认使用//build/suite/gn/hapsigntool提供的测试证书。 # 量产时务必通过external_deps和产品级配置指向厂商正式证书 hap_profile ./module.json5 # 指向HAP包对应的profile文件如果有 certificate_file //build/suite/gn/hapsigntool/test_certificate.pem certificate_profile //build/suite/gn/hapsigntool/ohos_test.p7b private_key //build/suite/gn/hapsigntool/test_private_key_2048.pem }关键解释ohos_prebuilt_hap这是OpenHarmony构建系统提供的模板专门用于处理预编译好的HAP包集成。part_name这个参数非常重要。它定义了应用在/system/app/下的子目录名。多个预制应用可以使用相同的part_name它们会被归类到同一目录。4.2 步骤二将应用部件添加到产品配置现在我们需要告诉产品的构建系统让它包含我们刚刚定义的myapp_hap部件。编辑产品配置文件//vendor/hihope/rk3566/config.json。找到subsystems部分定位到applications子系统。{ subsystems: [ { subsystem: applications, components: [ { component: prebuilt_apps, features: [] }, // ... 其他已存在的部件如 launcher, settings 等 ] }, // ... 其他子系统 ] }你需要确保components列表里包含prebuilt_apps。如果不存在就添加它。这里的component: prebuilt_apps必须与步骤一中BUILD.gn里定义的part_name严格对应。4.3 步骤三可选但推荐通过特性开关控制为了更灵活地管理哪些应用被预制例如为不同型号的产品配置不同的应用列表我们可以使用特性feature机制。在//vendor/hihope/rk3566/features/目录下创建一个文件例如prebuilt_apps.json。{ Features: { prebuilt_apps: [ myapp ] // 这个“myapp”是一个特性标识符 } }修改步骤一中的BUILD.gn使其受特性控制。# //vendor/hihope/rk3566/prebuilt-apps/MyApp/BUILD.gn import(//build/ohos.gni) # 判断是否启用myapp特性 if (has_feature(prebuilt_apps_myapp)) { ohos_prebuilt_hap(myapp_hap) { module_name myapp_hap source ./MyApp.hap install_enable true subsystem_name applications part_name prebuilt_apps // ... 签名配置 } }在产品的config.json中关联这个特性文件。{ product_name: rk3566, version: 4.1.0, device_company: hihope, // ... 其他配置 features: { prebuilt_apps: [ //vendor/hihope/rk3566/features/prebuilt_apps.json ] } }这样只有当prebuilt_apps_myapp特性被激活时MyApp才会被编译进系统。你可以通过命令行hb build --gn-args “prebuilt_apps_myapptrue”来激活它或者在产品config.json的features里默认开启。4.4 步骤四编译与验证完成所有配置后进入源码根目录执行全量编译hb build -f编译过程会读取产品配置包含applications子系统的prebuilt_apps部件。在prebuilt_apps部件中查找BUILD.gn目标。找到我们的myapp_hap目标将其声明的MyApp.hap文件复制到中间目录并使用指定证书重新签名如果需要。将处理后的HAP包打包到system镜像的/system/app/prebuilt_apps/目录下。生成最终的update.img等镜像文件。编译成功后的验证刷写镜像到RK3566开发板。设备启动后进入终端通过hdc shell连接。执行以下命令检查# 查看应用是否已安装 bm dump -a | grep com.example.myapp # 查看HAP包实际存放路径 ls -l /system/app/prebuilt_apps/如果能看到你的应用信息并且/system/app/prebuilt_apps/目录下存在对应的.hap文件恭喜你预制成功了5. 进阶配置为默认应用仅仅预装还不够我们可能希望应用成为特定操作的默认选择例如让我们的浏览器成为打开.html文件的默认应用。这需要修改系统的install_list_capability.json文件。该文件定义了系统对特定Intent意图的默认响应规则。该文件通常位于//applications/standard/launcher/module.json5同级的resources目录下或者由具体产品定制。操作流程需谨慎建议先备份定位文件在你的产品代码或applications子系统代码中搜索install_list_capability.json。理解结构该文件包含一个install_list数组每个元素是一个应用的能力声明。添加配置为你预制的应用添加一个条目。例如将其设为浏览器{ bundleName: com.example.myapp, // 你的应用包名 moduleName: entry, // 你的模块名通常是entry abilityName: MainAbility, // 你的Ability名 app_signature: [...], // 应用的签名信息必须匹配 defaultEnable: true, relatedCapabilities: [ { name: ohos.want.action.viewData, entities: [entity.system.browsable], uris: [ { scheme: http }, { scheme: https } ], type: text/html } ] }这段配置告诉系统对于action为ohos.want.action.viewData查看数据、entity包含entity.system.browsable可浏览、类型为text/html或scheme为http/https的请求默认启用com.example.myapp应用。重新编译修改此文件后需要重新编译系统镜像并烧录。重要警告修改默认应用配置属于深度系统定制如果配置错误可能导致系统服务异常。务必在测试板上充分验证并确保签名信息完全正确。建议先从一个简单的filescheme 类型开始测试。6. 常见问题与排查实录在实际操作中你几乎一定会遇到下面这些问题。我把踩过的坑和解决方案记录下来希望能帮你节省大量时间。6.1 编译失败Part “prebuilt_apps” not found现象编译时报错提示找不到prebuilt_apps部件。原因产品config.json中applications子系统的components列表里没有添加prebuilt_apps或者拼写不一致。排查检查//vendor/hihope/rk3566/config.json。确认component的名字与BUILD.gn中part_name完全一致大小写敏感。确认该部件所在的路径即你的BUILD.gn文件所在的目录被构建系统扫描到。通常BUILD.gn需要放在一个被subsystem的components所引用的部件目录下。我们的做法是在产品目录下创建并通过config.json直接引用部件名这是一种标准做法。6.2 应用未出现编译成功但设备上找不到应用现象刷机后桌面没有图标bm dump也找不到。原因1签名不匹配或无效。这是最常见的原因。预置应用的签名必须能被系统接受。调试证书在user版本的镜像中可能被禁用。解决检查编译日志看是否有关于签名验证的警告或错误。临时解决方案编译userdebug版本进行测试 (hb build --target-cpu arm64 --build-type userdebug)。最终方案配置产品使用厂商正式证书。这涉及修改//productdefine/common/base/或产品目录下的signature相关配置替换BUILD.gn中的certificate_file等路径。原因2应用安装失败。系统在启动阶段尝试安装/system/app/下的HAP包时失败。排查adb shell或hdc shell连接设备。查看系统日志过滤AppInstall或BundleManager相关错误logcat | grep -E “(install|fail|error)”。常见错误包括包解析失败HAP包损坏、权限声明错误申请了未授权的权限、module.json5格式错误。6.3 默认应用配置不生效现象修改了install_list_capability.json但打开文件时依然弹出选择框。原因1配置格式或路径错误。系统可能没有加载到你修改的文件。排查确认你修改的文件最终被编译到了system镜像中。可以在设备上查找该文件find /system -name “install_list_capability.json”并检查其内容。原因2签名信息不匹配。app_signature字段必须填写应用签名证书的指纹SHA256。获取指纹命令openssl x509 -in your_certificate.pem -noout -fingerprint -sha256。必须去掉冒号转换为大写。这个字段必须完全正确否则匹配失败。原因3能力声明冲突。可能有其他应用也声明了相同的能力且优先级更高。检查配置中是否有”defaultEnable”: false的覆盖项。6.4 存储空间与分区大小问题预置的应用过多或HAP包太大导致system分区空间不足编译失败。解决查看system分区大小配置通常在//vendor/hihope/rk3566/下的partition.csv或cfg文件中定义。优化应用体积压缩资源。如果应用确实很大考虑将其预置到vendor分区如果产品有规划。这需要修改BUILD.gn中的安装路径和产品分区配置。7. 实操心得与优化建议走通整个流程后我有几点深刻的体会规划先行在开始修改代码前花时间规划好你的预制应用管理策略。是全部放在一个prebuilt_apps部件里还是按功能分多个部件是否使用特性开关统一的规划能避免后续目录和配置混乱。签名是命门一定要尽早建立正式的签名证书管理流程。调试阶段可以用测试证书过关但进入联调或量产阶段签名问题会集中爆发导致进度阻塞。建议在项目初期就准备好发布证书并搭建对应的编译环境。充分利用编译缓存在调试BUILD.gn和配置文件时不需要每次都hb build -f全量编译。如果只修改了BUILD.gn或资源文件可以只编译你的部件hb build prebuilt_apps。这能节省大量时间。版本管理预置在系统里的应用其版本号在module.json5中定义是固定的。如何升级通常有两种策略一是通过后续的系统OTA升级整个镜像二是将应用设计为可覆盖安装需要签名一致然后通过应用市场推送更新。需要在产品设计阶段就考虑清楚。测试要全面预置应用测试不能只看能否安装。要测试冷启动刷机后第一次开机应用是否正常出现。权限交互应用申请的权限是否正常弹窗如果权限级别需要用户授权。默认应用行为如果配置了默认应用用其他应用触发对应的Intent看是否能正确跳转。卸载与恢复尝试通过非正常手段卸载后恢复出厂设置能否再次出现。最后为RK3566这类性能不错的开发板预置应用时可以稍微“大方”一点但也要注意控制system分区的大小。一个良好的习惯是在产品的README文档中详细记录每一个预制应用的名称、版本、预制原因、配置路径和签名信息这对未来的维护和团队协作至关重要。