HarmonyOS(鸿蒙)上架流程与构建文档
目录
- 第一部分 上架完整流程
- 1. 流程总览
- 2. 上架前需要准备的材料
- 3. 注册华为开发者账号
- 4. 先理解鸿蒙的签名体系
- 5. 申请认证文件
- 6. 把签名配置接入工程
- 7. AGC 创建应用并提交审核
- 8. 常见驳回原因
- 9. 上架后的版本更新
- 第二部分 构建与打包操作文档
- 10. 工程定位
- 11. 环境与开发工具
- 12. 运行方式
- 13. 原生桥接能力
- 14. 把 Web 产物放进鸿蒙工程
- 15. 测试包与上架包打包流程
- 16. 注意事项
- 第三部分 常见坑
第一部分 上架完整流程
1. 流程总览
鸿蒙的签名体系介于 Android 和 iOS 之间:密钥库(.p12)是你自己在本地生成的(像 Android),但证书(.cer)和 Profile(.p7b)必须由华为签发(像 iOS)。所以本地生成 + 平台签发两头都要做。
准备资质材料
└─ 营业执照 / 身份证、软件著作权、隐私政策、App 备案
↓
注册华为开发者联盟账号
↓
实名认证(个人:身份证+人脸;企业:营业执照+对公打款验证)
↓
登录 AppGallery Connect(AGC)→ 证书、APP ID 和 Profile → APP ID → 新建
└─ 包名(Bundle Name)= com.d3.app_qyxh(设置后不可修改)
↓
在 APP ID 列表点【发布】→ 关联创建待发布应用(填支持设备、默认语言)
└─ 完成后才会出现在「APP 与元服务」列表里
↓
在 DevEco Studio 本地生成密钥库和请求文件
├─ release.p12 密钥库(含公私钥对,本地生成,本地保管)
└─ release.csr 证书请求文件(拿去 AGC 换证书)
↓
AGC → 证书、APP ID 和 Profile → 证书 → 新增证书 → 上传 .csr → 申请【发布证书】
└─ 下载得到 release.cer(每账号上限 3 个,实名开发者有效期 3 年)
↓
AGC → 证书、APP ID 和 Profile → Profile → 申请【发布 Profile】
├─ 绑定包名 com.d3.app_qyxh
├─ 绑定刚申请的发布证书(证书指纹由 AGC 自动写入,无需手动配置)
└─ 下载得到 release.p7b(一个应用上限 100 个 Profile)
↓
DevEco Studio 配置签名(p12 + 口令 + 别名 + cer + p7b)
↓
把 Web 产物手动放进 entry/src/main/resources/rawfile/dist
↓
hvigorw assembleApp --mode project -p product=default -p buildMode=release
↓
上传 build/outputs/default/Mobile-default-signed.app 到 AGC
↓
填写应用信息 → 提交审核 → 通过 → 上架
2. 上架前需要准备的材料
| 材料 | 说明 | 个人开发者 | 企业开发者 |
|---|---|---|---|
| 身份证 | 实名认证 | 必须(本人) | 法人/负责人 |
| 营业执照 | 企业主体资质 | 不需要 | 必须 |
| 对公银行账户 | 华为通过对公打款验证确认企业身份(打一笔小额,你回填金额) | 不需要 | 必须 |
| 企业邮箱 / 授权书 | 部分情况需要 | 不需要 | 可能需要 |
| 软件著作权证书 | 华为官方原文将软著列为「非必选资质」,但建议申请《计算机软件著作权登记证书》《APP电子版权证书》或《软件著作权认证证书》以保护知识产权;游戏类必需(软著 + 版号,且每份软著登记证书仅限对应一款游戏)。证书上的软件名称须与上架应用名称一致,著作权人须与开发者名称一致 | 视品类 | 视品类 |
| App 备案号 | 工信部要求,中国大陆分发的 App 需完成备案。备案在云服务商(接入商)的备案系统办理,须选「鸿蒙」平台并添加鸿蒙包名;多个包名须逐个备案(详见本节下方「备案要点」) | 需要 | 需要 |
| 电子版权证书(PDF) | 上架材料清单内的一项,上传入口为「AGC > APP与元服务 > 应用名称 > 版本信息 > 版权信息 > 电子版权证书」;纸质证书走「应用版权证书或代理证书」 | 视品类 | 视品类 |
| 《个人开发者承诺函》 | 个人开发者提交资质时需同时提供 | 必须 | 不需要 |
| 隐私权利网址 | 与隐私政策网址一并要求,两个网址都必须公网可访问 | 必须 | 必须 |
| 隐私政策链接 | 必须可公网访问,AGC 里是必填项 | 必须 | 必须 |
| 应用图标 | 216×216 PNG(华为文档没写死尺寸,以 AGC 上传页面的实际提示为准) | 必须 | 必须 |
| 应用截图 | 按 AGC 要求的机型尺寸 | 必须 | 必须 |
| 演示账号 | 审核员登录用。产物需要登录才能进主界面时必须提供 | 必须 | 必须 |
上表里软著与备案的口径按华为官方文档写;图标尺寸华为文档没写死,以 AGC 页面实时提示为准。
资质材料的图片格式硬要求:①原件拍照或彩色扫描件,或加盖公章的复印件;②必须在有效期内;③不可隔屏拍摄,边角完整、内容清晰(国徽不得遮挡);④色调背景一致、无反光;⑤水印只能一行且不遮挡重要信息;⑥支持格式 JPG / PNG / BMP / PDF。资质上传入口:AGC > APP与元服务 > 点击应用名称 > 版本信息 > 版权信息(游戏走「版权信息和版号」)。版权资质证件中的公司名称必须与开发者名称完全一致,若应用非开发者所有,需补《应用版权授权书》与相关证明(授权书须含授权方、被授权方、授权应用名称、授权细则、授权期限、授权方公章及日期;授权方为个人时还需手写签名 + 身份证正反面扫描件)。从事增值电信业务还需《增值电信业务经营许可证》。
备案要点(来源:华为《APP 备案指引》《应用审核 Checklist》):
- 备案不在华为做,在云服务商(接入商)的备案系统做 —— 华为云 / 阿里云 / 腾讯云 / 移动云 / 天翼云 / 联通云;
- 🔴 HarmonyOS 应用必须在接入商备案系统里选择「鸿蒙」平台并添加鸿蒙包名;
- 🔴 存在多个包名,或同时有 HarmonyOS 应用与元服务时,所有包名均需备案(可以添加多个);同一款 App 若已备案安卓/iOS,新增鸿蒙需申请变更备案。仓库默认 Android 是
com.d3.app、鸿蒙是com.d3.app_qyxh,两个包名都要备案;- 无需备案的两类:单机应用(未通过连接公共互联网提供互联网信息服务的移动应用)、境外应用(境外主体运营且服务器仅放置在境外);
- 同一主体下不同 App 名称不可重复;不同运行平台下同一款 App 的名称应保持一致;备案的应用包名、应用名称、主体信息必须与在架信息一致;
- 填「主体证件号」时要分清数字 5 与字母 S、数字 1 与字母 I、数字 0 与字母 O,这是最常见的填错项;
- 未备案的后果:影响华为应用市场的搜索与展示;安装时提示「应用未核准(备案)」;纯净模式增强防护开启后仅可安装经华为检测的应用;
- AGC 侧录入位置:应用信息页的「核准(备案)信息」模块。备案需要的证书公钥与指纹在发布证书详情页点「备案信息」获取(见 5.3);
- 非经营性互联网信息服务还需完成 ICP 备案(工信部 ICP/IP地址/域名信息备案管理系统),ICP 主办单位名称须与开发者名称一致,且与工信部系统登记信息一致。
个人 vs 企业:和 iOS 类似,应用市场上展示的开发者名称不同(个人显示姓名,企业显示公司名)。公司产品应走企业开发者(
app.json5里vendor当前还是占位值example,记得改)。
3. 注册华为开发者账号
3.1 注册
- 打开 https://developer.huawei.com/;
- 注册华为账号(建议用公司公共邮箱,不要用个人私人华为账号——账号丢了应用拿不回来);
- 登录后进入「开发者联盟」,选择成为开发者。
华为开发者联盟账号的注册与实名认证,在官方文档列出的方式中均不含任何收费项,不像 Apple 需要年费。
3.2 实名认证
这一步是硬门槛,没实名认证不能创建应用、不能申请证书。
个人开发者(四种方式任选其一):
| 认证方式 | 需要的材料 | 耗时 |
|---|---|---|
| 人脸识别(官方推荐) | 姓名 + 身份证号 + 人脸 | 即时完成 |
| 个人银行卡(官方推荐) | 姓名 + 身份证号 + 个人银行卡号 | 即时完成 |
| 人工审核 | 身份证等证件材料 | 1~2 个工作日 |
| 华为云授权认证 | 该华为账号已在华为云完成个人实名 | 即时 |
企业开发者(三种方式任选其一):
| 认证方式 | 需要的材料 | 耗时 |
|---|---|---|
| 打款认证(官方推荐) | 企业对公账号 + 法定代表人姓名 + 身份证号 | 最快 30 分钟 |
| 人工审核 | 营业执照原件扫描件或照片 + 法定代表人手持身份证正反面照片,或人脸识别 | 1~2 个工作日 |
| 华为云授权认证 | 该华为账号已在华为云实名为企业客户 | 即时 |
其他硬性限制:
- 企业认证暂不支持电子营业执照,须提供最新「三证合一」营业执照的照片或扫描件,且信息与国家企业信用信息公示系统一致;
- 政府机关 / 事业单位:提交统一社会信用代码证书或事业单位法人证书 + 法定代表人手持身份证正反面照片;
- 法定代表人为港澳台人士可提交手持通行证或护照照片,海外人士提供手持护照照片;
- 🔴 不支持港澳台、海外企业及海外个人注册认证中国大陆的开发者联盟账号,这类主体须去华为海外官网注册;
- 官方给出的认证方式列表中不含任何收费项。
企业认证最容易卡的点: - 企业名称有括号、简繁体差异 → 必须和执照一字不差,并与国家企业信用信息公示系统一致; - 走打款认证时,对公账户若是新开户或长期不动户,可能收不到打款或查不到流水; - 打款金额有回填次数限制,填错多次会锁定,需要重新发起; - 建议用企业公共邮箱与公共手机号注册,避免人员离职后账号失联。
3.3 认证通过后能做什么
| 平台 | 地址 | 用途 |
|---|---|---|
| 华为开发者联盟 | https://developer.huawei.com/ |
账号、实名、文档中心 |
| AppGallery Connect(AGC) | https://developer.huawei.com/consumer/cn/service/josp/agc/index.html |
主要工作台:「APP 与元服务」建应用/上传包/提交审核,「证书、APP ID 和 Profile」管 APP ID、证书、Profile |
上架包用到的签名文件(发布证书
.cer、发布 Profile.p7b)都在 AGC 的「证书、APP ID 和 Profile」里查看和下载,作废后也可以重新申请替换。
4. 先理解鸿蒙的签名体系
这一节是概念。四个文件搞不清关系,签名一定配不对。
| 文件 | 从哪来 | 作用 | 类比 |
|---|---|---|---|
.p12(示例命名 release.p12) |
本地生成(DevEco 向导或 keytool) | 密钥库,装着公私钥对,签名的私钥在这里面 | Android 的 release.jks |
.csr(示例命名 release.csr) |
本地生成(和 p12 同时产出) | 证书请求文件,只含公钥和身份信息,用来向 AGC 换证书 | iOS 的 CertificateSigningRequest |
.cer(示例命名 release.cer) |
AGC 签发(上传 csr 换来) | 华为签发的证书,证明这个公钥属于你 | iOS 的 .cer |
.p7b(示例命名 release.p7b) |
AGC 签发 | Profile 描述文件,把「证书 + 包名 + 权限(+ 调试设备)」绑在一起 | iOS 的 .mobileprovision |
关系图:
本地 DevEco 向导
├──► release.p12 (私钥,本地保管,绝不外传)
└──► release.csr (公钥请求)
│ 上传到 AGC「证书、APP ID 和 Profile」
▼
release.cer (华为签发的证书)
│
│ + 包名 com.d3.app_qyxh
▼
release.p7b (华为签发的 Profile)
│
┌──────────┴──────────┐
▼ ▼
p12 + 口令 + 别名 cer + p7b
└──── 一起填进 build-profile.json5 的 signingConfigs ────► 签名后的 .app
证书分两种,别搞混:
| 调试证书 / 调试 Profile | 发布证书 / 发布 Profile | |
|---|---|---|
| 用途 | 真机调试、内部测试 | 上架 AppGallery |
| 谁生成 | DevEco Studio 可以自动生成(一键) | 必须去 AGC 手动申请 |
| 需要设备 | 需要登记调试设备 | 不需要 |
| 数量限制 | 每个账号最多 3 个调试证书 | 每个账号最多 3 个发布证书;一个应用最多 100 个 Profile |
| 有效期 | 实名认证开发者 1 年;未实名认证开发者仅 14 天 | 实名认证开发者 3 年 |
| 账号权限 | 需具备「访问调试类证书」/「访问调试类 Profile」权限 | 需具备「访问发布类证书」/「访问发布类 Profile」权限 |
一句话记法:测试包用 DevEco Studio 自动生成的调试签名,上架包用 AGC 申请的发布签名(发布证书和 Profile 随时能在 AGC 平台查看、下载、重新申请),配图见
images/19.png。
5. 申请认证文件
5.1 第一步:AGC 创建 APP ID 并关联创建应用
🔴 这一步是两步流程(AGC 帮助《创建应用》,更新于 2026-07-22),旧版「我的应用 → 新建」已不是入口。
第 1 步:创建 APP ID
- 登录 AGC → 「证书、APP ID 和 Profile」→ 左侧「APP ID」→ 新建;
- 填写:
- 应用类型:App(元服务另选);
- 应用名称:应用市场展示名;
- 应用包名:填
com.d3.app_qyxh——必须与AppScope/app.json5的bundleName完全一致; - 应用分类;
- (可选)按需开启华为开放能力。
第 2 步:为 APP ID 关联创建待发布应用
- 在 APP ID 列表中找到刚创建的 APP ID → 点「发布」;
- 填写支持设备(壳里
module.json5是deviceTypes: ["phone"],选手机)、默认语言; - 完成后该应用才会出现在「APP 与元服务」列表中,后续上传包、填信息、提交审核都在那里做。
包名命名规范(不符合会直接建不出来):
- 以点号分隔,至少 3 段;
- 每段只允许字母、数字、下划线,首段必须以字母开头;
- 总长度 7~128 个字符,不允许连续点号;
- 保留字
oh/ohos/harmony/harmonyos/openharmony/system不能作为独立的一段; - 须与 DevEco 工程的 Bundle name 一致。
仓库默认包名
com.d3.app_qyxh对照上述规则是合规的(3 段、首段字母开头、无保留字段、长度合规),照这个格式换成自己的即可。⚠️ 不可逆项:应用包名与应用分类一经设置均不可修改。包名填错的后果见 16 节第 3 条。
⚠️ 支持设备在应用发布后,升级版本时只能增加、无法删除;开放能力的配置会写入 Profile,改动开放能力后必须重新下载 Profile。
⚠️ AGC 现在新建 HarmonyOS 应用默认即为 HarmonyOS 5.0 及以上(NEXT),不支持创建 3.1 / 4.0 及以下版本的应用;华为文档中标注「仅适用于发布存量 HarmonyOS 4.X 及以下应用」的那批页面对新建应用不适用。
5.2 第二步:本地生成密钥库 .p12 和请求文件 .csr
方式 A:DevEco Studio 向导(推荐)
- DevEco Studio 打开工程 → 菜单 File → Project Structure(项目结构);
- 切到 Signing Configs 标签;
- 先取消勾选
Automatically generate signature(自动生成签名)——勾着它是给调试用的; - 点 Key Store File 右侧的 New...(新建密钥库);
- 填写:
- Key store file:保存路径 + 文件名,例如
release.p12; - Password / Confirm password:密钥库口令(记牢,丢了没法找回);
- Alias:密钥别名,示例配置里用的是
release; - Key password / Confirm:密钥口令;
- Validity:有效期(年),建议填 25 年以上;
- Certificate 区域:First and last name、Organizational unit、Organization、City、Province、Country Code(CN);
- OK 后会生成
.p12; - 再点 Request File 右侧的按钮生成
.csr(会让你选保存路径,例如release.csr)。
方式 B:命令行 keytool(DevEco 装好后自带 JDK,也可用系统 JDK)
# 1) 生成密钥库 .p12(ECC 密钥,鸿蒙要求 SHA256withECDSA)
keytool -genkeypair `
-alias release `
-keyalg EC -sigalg SHA256withECDSA `
-dname "C=CN,O=YourCompany,OU=YourDept,CN=YourName" `
-keystore release.p12 -storetype pkcs12 `
-validity 9125 `
-storepass <密钥库口令> -keypass <密钥口令>
# 2) 生成证书请求文件 .csr
keytool -certreq `
-alias release `
-keystore release.p12 -storetype pkcs12 `
-storepass <密钥库口令> `
-file release.csr
注意签名算法:壳里
build-profile.json5的signAlg是SHA256withECDSA(椭圆曲线),不是 Android 常见的 RSA。用 keytool 时-keyalg要用EC,否则后面 AGC 换证书或签名会失败。
5.3 第三步:AGC 申请发布证书 .cer
当前路径:AGC → 「证书、APP ID 和 Profile」→ 左侧「证书」→「新增证书」(旧文档里的「用户与访问 → 证书管理」已不是当前入口)。
- 证书名称:自己起,例如
示例应用发布证书,不超过 100 个字符; - 证书类型:选 发布证书(Release);
- 上传 CSR 文件:选刚生成的
release.csr; - 提交 → 列表里会出现该证书 → 点下载,得到
.cer文件(示例命名release.cer)。
操作账号需具备「访问发布类证书」权限。
🔴 配额与有效期:
- 每个账号最多可申请 3 个发布证书;
- 实名认证开发者的发布证书有效期为 3 年;
- 证书到期暂不影响已在架的应用,但更新版本时上传用过期证书签名的包会失败;
- 证书状态变为「失效」或「已吊销」后,通过该证书申请的 Profile 会全部失效或吊销;
- 「废除」操作不可恢复,废除后其 Profile 全部失效(废除本身暂不影响在架应用);
- 🔴 更新版本时必须使用同一个 CSR 文件生成的证书,换了 CSR 就得连 Profile 一起换;
- 证书详情里点「备案信息」可获取证书公钥和指纹,用于 App 备案填报;AGC 16.5.1 之前创建的发布证书不展示备案信息,这种情况需重新申请证书才能拿到。
5.4 第四步:AGC 申请发布 Profile .p7b
当前路径:AGC → 「证书、APP ID 和 Profile」→ 左侧「Profile」→ 添加。
- Profile 名称:例如
release; - 类型:选 发布(Release);
- 选择包名:
com.d3.app_qyxh(能选到的前提是 5.1 已创建 APP ID); - 选择证书:勾上 5.3 申请的发布证书;
- 受限权限(ACL):🔴 申请 ACL 权限的入口在项目下的「ACL 权限」页签,创建 Profile 时只能添加已经获取到的 ACL 权限,不能在这里发起申请。壳里只声明了 INTERNET / GET_NETWORK_INFO / CAMERA 三个普通权限,没有 ACL 受限权限,这一步跳过(见 16 节权限表);
- 提交 → 下载得到
.p7b(示例命名release.p7b)。
操作账号需具备「访问发布类 Profile」权限。
🔴 重要变化:Profile 申请成功时,AGC 会自动把所关联发布证书的指纹添加到该应用/元服务,不需要再手动配置公钥指纹。旧流程里「申请完 Profile 还要手动去填证书指纹」这一步已经不需要了。若提示指纹数量达到上限,先删掉不需要的指纹再手动配置。
一个应用最多可以有 100 个 Profile。
Profile 里绑死了包名。改了包名,旧 Profile 直接不可用,必须重新申请;换了发布证书也必须用新证书重新生成 Profile。
5.5 调试签名(测试包用,不用手动申请)
测试阶段完全不需要走 5.3 / 5.4:
- DevEco Studio → File → Project Structure → Signing Configs;
- 勾选
Automatically generate signature(自动生成签名); - 用 DevEco 登录你的华为开发者账号;
- DevEco 会自动帮你申请调试证书 + 调试 Profile,并把设备 UDID 登记上去。
🔴 调试证书的配额与有效期:
- 每个账号最多可申请 3 个调试证书;
- 实名认证开发者的调试证书有效期为 1 年;未实名认证的开发者只有 14 天;
- 更新调试证书后,必须同步更新调试 Profile 和公钥指纹,否则真机装不上;
- 操作账号需具备「访问调试类证书」权限。

图中红字标注了这两条路:「测试选择这个会自动生成」指的是自动签名勾选项;「上架包自己配置签名文件」指的是手动填 5.2~5.4 拿到的四个文件。
首次连真机注意:DevEco 自动签名会把当前连接的设备登记进调试 Profile。换新电脑或换新设备第一次调试时,要确认工程的
compatibleSdkVersion覆盖真机的系统版本,否则装不上。
5.6 认证文件的保管要求
.p12 的重要性等同 Android 的 release.jks:
- 丢了
.p12或忘记口令 → 无法用同一身份签名,已上架应用的更新会受影响(华为侧需走证书替换流程,比较麻烦); - 四个文件(
.p12/.csr/.cer/.p7b)+ 两个口令(storePassword / keyPassword)+ 别名,一起存到公司密码管理器 / 加密盘,至少两处异地备份; - 绝对不能提交到 Git 仓库;
- 谁能拿到要有记录;人员离职要评估。
.cer和.p7b可以随时从 AGC 重新下载,.p12不能。备份的重点是.p12+ 口令。
6. 把签名配置接入工程
6.1 DevEco Studio 图形界面(推荐)
- File → Project Structure → Signing Configs;
- 取消勾选
Automatically generate signature; - 依次填四项:
- Store File:选
.p12; - Store Password:密钥库口令;
- Key Alias:
release; - Key Password:密钥口令;
- Sign Alg:
SHA256withECDSA(一般自动带出); - Profile File:选
.p7b; - Certpath File:选
.cer; - Apply / OK。DevEco 会把这些值写回
build-profile.json5。

图中同时展示了「项目结构 → 基础信息」页:包名
com.d3.app_qyxh、Compatible SDK6.0.2(22)。⚠️ 图里
storePassword/keyPassword两行的值被遮盖了,这两个是你自己的口令,不要外传、不要截图外发。
6.2 build-profile.json5 的结构
配置最终落在工程根目录的 build-profile.json5:
{
"app": {
"signingConfigs": [
{
"name": "default",
"type": "HarmonyOS",
"material": {
"storeFile": "<绝对路径>/release.p12",
"storePassword": "<DevEco 加密后的密文>",
"keyAlias": "release",
"keyPassword": "<DevEco 加密后的密文>",
"signAlg": "SHA256withECDSA",
"profile": "<绝对路径>/release.p7b",
"certpath": "<绝对路径>/release.cer"
}
}
],
"products": [
{
"name": "default",
"signingConfig": "default",
"compileSdkVersion": "6.1.1(24)",
"targetSdkVersion": "6.1.1(24)",
"compatibleSdkVersion": "6.0.2(22)",
"runtimeOS": "HarmonyOS",
"buildOption": {
"strictMode": { "caseSensitiveCheck": true, "useNormalizedOHMUrl": true }
}
}
],
"buildModeSet": [ { "name": "debug" }, { "name": "release" } ]
},
"modules": [
{ "name": "entry", "srcPath": "./entry",
"targets": [ { "name": "default", "applyToProducts": [ "default" ] } ] }
]
}
几个要点:
| 项 | 说明 |
|---|---|
storePassword / keyPassword |
DevEco 会把口令加密后再写进文件,不是明文。这一点比 Android 的 build.gradle(明文口令)安全,但加密串仍然是敏感信息,仍然不能提交到公开仓库——它在同一台机器/同一 DevEco 环境下可以直接用来签名 |
storeFile / profile / certpath |
写的是绝对路径。换电脑、换目录必须改,这是最常见的构建失败原因 |
signAlg |
SHA256withECDSA,与 5.2 生成密钥时的算法必须一致 |
compileSdkVersion / targetSdkVersion |
6.1.1(24),编译用的 SDK |
compatibleSdkVersion |
6.0.2(22),最低兼容版本,决定哪些真机能装 |
runtimeOS |
HarmonyOS(不是 OpenHarmony) |
products[0].name |
default——打包命令里的 -p product=default 就是指这个,改了名字命令也要改 |
products[0].signingConfig |
必须有这一行,值等于 signingConfigs[].name(这里两边都是 default)。少了它会静默出未签名包,见下面的警告 |
buildModeSet |
定义了 debug / release,对应命令里的 -p buildMode=release |
⚠️ 最坑的一条:
products[].signingConfig缺失时,打包照样BUILD SUCCESSFUL,但出来的是未签名包。
signingConfigs只是「声明有哪些签名配置」,真正让它生效的是products[]里"signingConfig": "default"这一行关联。两者一断开——比如只清空了signingConfigs: []却漏了products里的关联,或者反过来——hvigor 不报错、不中断,只在日志里留一行 WARN:WARN: No signingConfig found for product default.结果是
build/outputs/default/下只有Mobile-default-unsigned.app,没有-signed.app,上传 AGC 直接被拒。判断方法:看构建日志里有没有真正执行
SignHap和SignApp这两个任务(各一两秒)。没有这两个任务就是没签名,别只看最后那句BUILD SUCCESSFUL。注意:仓库里的
build-profile.json5不带签名配置 ——signingConfigs是空数组[],products[0]里也没有signingConfig这一行。所以克隆下来直接打 release 包,只会得到-unsigned.app。补齐方式二选一:
- 推荐:按 6.1 节在 DevEco Studio 里配一遍签名,DevEco 会把
signingConfigs[0]和products[0].signingConfig两处一起写回去;- 手动改
build-profile.json5:照上面的结构填好signingConfigs[0],并且别忘了给products[0]补上"signingConfig": "default"。
6.3 应用级配置 AppScope/app.json5
{
"app": {
"bundleName": "com.d3.app_qyxh",
"vendor": "example",
"versionCode": 1000000,
"versionName": "1.0.0",
"icon": "$media:layered_image",
"label": "$string:app_name"
}
}
| 项 | 仓库默认值 | 上架相关说明 |
|---|---|---|
bundleName |
com.d3.app_qyxh |
必须与 AGC 创建的应用包名、Profile 绑定的包名三者完全一致 |
vendor |
example |
DevEco 模板的默认值。上架前改成自己的公司/组织标识 |
versionCode |
1000000 |
整数,每次上传必须比上一次大,否则 AGC 拒收 |
versionName |
1.0.0 |
用户看到的版本号 |
icon |
$media:layered_image |
分层图标资源,在 entry/src/main/resources 里 |
label |
$string:app_name |
应用名,在 entry/src/main/resources/base/element/string.json 里 |
7. AGC 创建应用并提交审核
7.1 上传安装包
- AGC → APP 与元服务 → 选中应用 → 版本信息;
- 上传软件包:选
Mobile-default-signed.app; - 🔴 上传时的「使用场景」必须选「测试和正式上架」。若选了「仅测试」,后面做版本选取时会找不到这个包。
⚠️ 必须是
-signed.app,不能是-unsigned.app。两个文件同在build/outputs/default/目录下、大小只差几 KB,非常容易拿错,unsigned 包上传会直接被拒。
包体规范:
- APP 包总大小 ≤ 4GB;单个 HAP 上限:手机/平板 4GB、智能手表/智慧屏 2GB、路由器 200MB、运动手表 20MB;
- 所有 HAP 必须是非免安装的,即 Stage 模型下
AppScope/app.json5的bundleType为app; - 包名必须与创建 APP ID 时填的完全一致;
- 上架前 AGC 会出自检报告(通过 / 通过但存在问题 / 不通过并给错误码),不通过的先按错误码修。
上面的「使用场景」与包体规范取自华为《发布 HarmonyOS 应用》,AGC 页面偶有调整,具体数值以上传页的实际提示为准。
7.2 填写应用信息(必填清单)
| 项 | 说明 |
|---|---|
| 应用名称 / 简介 / 介绍 | 字数限制:应用介绍 ≤ 8000 字;一句话简介中文 ≤ 17 个字符;新版本特性(中国大陆)≤ 500 个字符 |
| 应用图标 / 截图 | 按 AGC 页面提示的尺寸。有「名称图标一致性」检测,应用名称与图标必须与安装后终端上显示的一致 |
| 应用分类、标签 | 应用分类在创建 APP ID 时已定,不可修改 |
| 隐私政策网址 | 必填,必须公网可访问 |
| 隐私权利网址 | 与隐私政策网址一并要求,同样必须公网可访问 |
| 隐私标签 | 需如实填写 |
| 权限说明 | 逐个说明申请的权限用途。壳里声明了 CAMERA,要说明用途(module.json5 里 reason 指向 $string:camera_permission_reason) |
| 演示账号 / 测试说明 | 产物是登录态 App 时必须提供。🔴 硬要求:测试账号在「提审页面 > 应用审核信息 > 测试账号」处填写,且该账号不能有权限、角色、会员或付费限制,审核人员要能完整走完登录 → 浏览 → 操作 → 退出全流程。若需连内网服务器,要在测试说明里写清服务器地址或说明已在账号中预置 |
| 核准(备案)信息 | AGC 应用信息页有独立的「核准(备案)信息」模块,填工信部备案号 |
| 版权信息 / 电子版权证书 | 入口为「版本信息 > 版权信息」;软著属非必选资质,电子版权证书 PDF 在上架材料清单内;游戏走「版权信息和版号」 |
| 版本号、更新说明 | 与 versionName 对应 |
| 上架国家/地区 | 🔴 选择中国大陆以外的地区时,必须勾选「同意应用数据出境声明」,否则无法提交审核 |
| 发布方式 | 立即发布 / 定时发布 |
7.3 提交审核
信息填全 → 提交审核。
华为官方文档未给出审核时长的承诺值。状态在 AGC 的应用版本信息页可见,被拒会给出具体条目和截图。
催审与撤销:
- 入口在 AGC → APP 与元服务 → 版本信息页右上角的「催审」/「撤销审核」;
- 🔴 审核中无法编辑版本信息,发现填错了必须先「撤销审核」;
- 撤销后状态变为「已撤销上架」,需要重新提交审核;
- 提交邀请测试时,可以同步提交「上架自检」,提前暴露问题。
8. 常见驳回原因
| 驳回原因 | 与这个壳的关系 | 处理 |
|---|---|---|
| 包名不一致 | 测试包名与上架包名可能不同 | 打上架包前核对 app.json5 的 bundleName = com.d3.app_qyxh,见 16 节第 3 条 |
| 上传了 unsigned 包 | 产物目录里两个 .app 长得像 |
只传 Mobile-default-signed.app |
| 需要登录但没给演示账号 | 产物需要登录才能进主界面时高危 | 在测试说明里填可用账号密码 |
| 需要连私有服务器,审核员连不上 | 产物连的是自有服务器或内网服务器时 | 说明清楚;确保服务器公网可达 |
| 权限申请未说明用途 / 申请了不必要的权限 | 壳里声明了 CAMERA | 确认 camera_permission_reason 文案具体(说明是「扫描二维码配置服务器」而不是笼统的「使用相机」) |
| 隐私政策缺失或不可访问 | 提供有效 URL | |
| 应用仅是网页封装、缺少原生价值 | 这就是个 WebView 壳,高危 | 强调调用了原生能力(相机、文件、日志、状态栏、热更新桥接,见第 13 节) |
| 动态下发代码 / 热更新 | 壳里通过 UpdaterBridge.ets 支持前端热更新 |
只更新已审核功能的 Web 资源,不新增未审核功能;不要在审核期间下发差异内容 |
| 备案缺失 | 中国大陆分发必备 | 提前在云服务商备案系统办,选「鸿蒙」平台并添加鸿蒙包名(见第 2 节备案要点)。注意:软著是「非必选资质」(游戏除外),驳回主因是备案而不是软著 |
| 崩溃 / 白屏 | rawfile/dist 没同步进包时会白屏 |
打包前确认 entry/src/main/resources/rawfile/dist 里有最新产物,见第 14 节 |
| SDK 版本与目标设备不匹配 | compatibleSdkVersion 决定可安装范围 |
按目标设备调 compatibleSdkVersion |
| 应用名称是泛词 | 不得使用「免费壁纸」这类泛词,也要避免电话/邮件/日历等广义词 | |
| 同类应用已过多的品类 | 官方明确建议避开敲木鱼、随机选择、计时、计算器、手电筒、记事本、记账、天气、数字大小写转换等同类过多的品类 | |
| 鸿蒙版质量低于已有其他版本 | 🔴 同一个 App 已经有安卓 / iOS 版时直接适用 | 官方原文:「若应用已有面向用户的其他版本,开发鸿蒙版本时质量与完善程度不得低于其他版本」。鸿蒙版功能不能是安卓版的缩水版 |
| 隐私政策未在首启弹窗展示 | 隐私政策须在首次启动弹窗或注册/登录界面显著展示;用户同意前不得收集个人信息、不得申请权限(含第三方 SDK 的行为) | |
| UX 不达标 | 硬指标示例:信息文本与背景色的对比度不得小于 3 | |
| 文案违规 | 禁用「国家级/最高级/最佳」等违反广告法的表述;禁止出现 test / demo / beta 字样 |
|
| 备案主体证件号填错 | 填「主体证件号」时分清数字 5 与字母 S、数字 1 与字母 I、数字 0 与字母 O |
9. 上架后的版本更新
- 改代码 → 提升版本号:
AppScope/app.json5的versionCode必须递增(如1000000→1000001);versionName按需改(如1.0.0→1.0.1);- 重新构建 H5 产物 → 同步到
rawfile/dist(第 14 节)→ 重新hvigorw assembleApp; - AGC → 应用 → 创建新版本 → 上传新
.app→ 填更新说明 → 提交审核。
关于走热更新而不是走商店更新
- 能做:修 Web 层 bug、调样式、改文案,通过
UpdaterBridge.ets下发新的前端资源,不用过审; - 不能做:新增未审核的功能、改变应用用途。这与 Apple 的限制同理,华为侧同样禁止绕过审核;
- 原生层改动必须走商店更新:新增 bridge、改
module.json5权限、改 SDK 版本,热更新覆盖不到。
第二部分 构建与打包操作文档
本部分对应
Mobile当前的鸿蒙壳工程结构,配置项均已与仓库文件核对。原文里的本机绝对路径(如D:\work\...)已统一替换为相对说明。
10. 工程定位
10.1 这个工程是什么
Mobile 是独立的 HarmonyOS 壳工程,用 ArkWeb 加载放进来的 Web 产物,并补齐鸿蒙侧需要的原生能力(文件、日志、状态栏、权限、热更新)。工程里不含任何 Web 业务代码。
它需要的 Web 产物由你自己在别的项目里构建,然后手动放进 entry/src/main/resources/rawfile/dist/(见第 14 节)。壳工程本身只负责:
- 用 ArkWeb / WebView 加载产物的入口页面;
- 把 Capacitor 那套调用接到鸿蒙原生能力上(见第 13 节);
- 产出可安装的
.hap/ 可上架的.app。
10.2 和 Android / iOS 壳的关系
三个壳彼此独立,只是接收同一份 Web 产物:
| 平台 | 壳工程 | 产物放哪 | 同步方式 |
|---|---|---|---|
| Android | open_h5/android |
open_h5/dist |
npx cap copy android(命令自动拷) |
| iOS | open_h5/ios |
open_h5/dist |
npx cap copy ios(命令自动拷) |
| HarmonyOS | Mobile/ |
Mobile/entry/src/main/resources/rawfile/dist |
手动拷贝,鸿蒙侧没有 Capacitor CLI |
一句话:业务逻辑改 Web 产物,端上能力改壳工程。
11. 环境与开发工具
| 项 | 要求 | 备注 |
|---|---|---|
| DevEco Studio | 6.1 版本 | 开发工具版本决定 SDK 版本,进而影响真机调试能否成功,推荐暂时使用 6.1 版本。例如 6.1.1.290 |
| HarmonyOS SDK | 随 DevEco 安装 | 工程 compileSdkVersion = 6.1.1(24),compatibleSdkVersion = 6.0.2(22) |
| hvigor | 随 DevEco 自带 | 例如 6.24.3,工具位置 <DevEco 安装目录>/tools/hvigor/bin/hvigorw.bat |
| ohpm | 随 DevEco 自带 | 鸿蒙包管理器,位置 <DevEco 安装目录>/tools/ohpm/bin |
| Node | 随 DevEco 自带 | 位置 <DevEco 安装目录>/tools/node;壳工程不需要另外装前端工具链 |
| 华为开发者账号 | 真机调试 / 上架都需要 | 见第 3 节 |
| 真机 | 鸿蒙设备 | 系统版本要被 compatibleSdkVersion 覆盖 |
| 工程路径 | 必须是纯 ASCII 路径(不能含中文) | ⚠️ 硬限制,详见第三部分 |
工程根目录关键文件:
| 文件 | 说明 |
|---|---|
build-profile.json5 |
签名配置、product、SDK 版本、buildMode(见 6.2) |
AppScope/app.json5 |
包名、版本号、图标、应用名(见 6.3) |
entry/src/main/module.json5 |
模块配置、Ability、权限声明 |
hvigorfile.ts |
hvigor 构建入口,内容是模板默认(appTasks,无自定义插件) |
oh-package.json5 / oh-package-lock.json5 |
鸿蒙依赖清单 |
local.properties |
本机 SDK 路径,不入库(.gitignore 已忽略) |
code-linter.json5 |
ArkTS 代码检查配置 |
.gitignore 当前已忽略:/node_modules、/oh_modules、/local.properties、/.idea、**/build、/entry/src/main/resources/rawfile/dist、/.hvigor、/.appanalyzer、/release、.cxx、/.clangd 等,以及全部签名材料 *.p12、*.p7b、*.cer、*.csr、*.jks、*.keystore。
12. 运行方式
当前鸿蒙工程的核心页面:
Mobile/entry/src/main/ets/pages/Index.ets
它的加载方式(见 Index.ets):
- WebView 的
src指向一个离线虚拟域:https://www.harmony.local/index.html?v=<启动时间戳>; - 落在这个域下的所有请求都被
.onInterceptRequest()接走,转成读取$rawfile('dist/<相对路径>'); - 所以真正被加载的文件是:
Mobile/entry/src/main/resources/rawfile/dist/index.html
Mobile/entry/src/main/resources/rawfile/dist/assets/**
- URL 上的
?v=取的是Date.now(),每次启动都不同,因此换了产物不需要手动改版本号,也不会读到旧缓存。
dist 放置位置:

⚠️
rawfile/dist是应用运行必需的资源,内容是你自己构建好的 Web 产物。它属于产物,仓库里不带这份目录(rawfile/是空目录,rawfile/dist也在.gitignore里),克隆下来后必须先按第 14 节手动放一次,否则应用起来是白屏。同时它也不能当无关文件删掉,更不要手写维护。
放好之后 rawfile/ 下应该是这样(具体文件取决于你用的打包器):
entry/src/main/resources/rawfile/
└── dist/
├── index.html ← 必须在 dist 根目录
└── assets/ ...
13. 原生桥接能力
为了让 Web 产物里原有的 Capacitor 调用在鸿蒙上继续可用,壳工程自带一套桥接层,位于 Mobile/entry/src/main/ets/bridge/:
| 文件 | 提供的能力 | 对应 Capacitor 插件 |
|---|---|---|
FilesystemBridge.ets |
文件读写、目录创建、读取、删除、重命名、stat、getUri |
@capacitor/filesystem |
LoggerBridge.ets |
前端日志写入、读取、清理、导出 | 自有日志能力 |
PermissionBridge.ets |
相机权限、存储目录检查 | 权限相关 |
StatusBarBridge.ets |
状态栏样式、背景色、显示隐藏、安全区 | @capacitor/status-bar |
UpdaterBridge.ets |
热更新:下载、切换、加载更新后的前端资源 | @capgo/capacitor-updater |
BridgeError.ets |
桥接层统一错误类型 | — |
辅助工具在 Mobile/entry/src/main/ets/utils/:FileManager.ets(沙盒路径与文件操作封装)、Logger.ets(日志落盘)。
这些桥接只覆盖上表列出的能力。如果你的 Web 产物用到了别的 Capacitor 插件,鸿蒙侧需要自己在
bridge/下按同样写法补一个。
HarmonyOS 真机的日志:设备连接编辑器后,在编辑器的「设备文件浏览」模块的沙盒中可见。
14. 把 Web 产物放进鸿蒙工程
鸿蒙侧没有 Capacitor cap copy 那种同步命令(Mobile 下没有同步脚本,hvigorfile.ts 是模板默认内容),这一步一直是手动放:
- 在别的项目里把 Web 产物打好包,得到一个含
index.html的目录; - 把它整个放到下面这个位置,目录名必须叫
dist:
Mobile/entry/src/main/resources/rawfile/dist/
├── index.html ← 入口,必须在 dist 根目录
└── assets/ ... ← 其余静态资源,内部结构不限
- 放完直接接第 15 节打包,中间不需要在 DevEco Studio 里做任何操作(如果 DevEco 正开着,先
Build → Clean Project一次更稳)。
⚠️ 换产物时先把旧的
dist整个删掉再放新的。多数打包器产出的assets/*.js文件名带内容哈希,直接覆盖不会顶掉旧文件,会在包里堆积无用文件、白白撑大安装包。⚠️ 只删到
dist这一级,别把上一级rawfile整个删掉 —— 以后rawfile下放了其他随包资源会跟着一起丢。产物放进
rawfile/dist之后,直接跑第 15 节的打包命令就能产出签名包。
15. 测试包与上架包打包流程
15.1 两者的区别
测试包和上架包的唯一区别是签名配置不一样:
| 测试包 | 上架包 | |
|---|---|---|
| 签名 | DevEco Studio 自动生成的调试签名(勾 Automatically generate signature) |
手动配置发布签名(.p12 + .cer + .p7b,见第 5、6 节) |
| 用途 | 真机调试、内部测试 | 上传 AGC 上架 |
| 注意 | 首次连接电脑/设备要注意当前使用的 SDK 是否支持该设备 | 必须核对包名,见 16 节第 3 条 |

15.2 打包命令
hvigorw assembleApp --mode project -p product=default -p buildMode=release
但 hvigorw 默认不在 PATH 里,而且它要靠环境变量 DEVECO_SDK_HOME 才能找到 HarmonyOS SDK。不开 DevEco Studio、纯命令行打包时用下面这个完整形式,这样能跑通:
cd <仓库根>\Mobile
$env:DEVECO_SDK_HOME = '<DevEco 安装目录>\sdk'
& '<DevEco 安装目录>\tools\hvigor\bin\hvigorw.bat' assembleApp --mode project `
-p product=default -p buildMode=release --no-daemon
DEVECO_SDK_HOME不设,hvigor 找不到 SDK,直接失败;--no-daemon不是必须的,但一次性打包加上它可以避免 hvigor 后台常驻进程占住build目录,后面清产物时省事。
参数含义:
| 参数 | 含义 |
|---|---|
assembleApp |
构建 .app(上架用的应用包)。构建 .hap(单模块安装包)用 assembleHap |
--mode project |
工程级构建(而不是单模块) |
-p product=default |
用 build-profile.json5 里 products[0].name = default 这个 product |
-p buildMode=release |
用 release 模式(对应 buildModeSet 里的 release) |
也可以直接在 DevEco Studio 里点菜单 Build → Build Hap(s)/APP(s) → Build APP(s),等价于上面这条命令。
15.3 产物位置
打包后的包文件在工程的 build/outputs/default/ 目录:
| 文件 | 说明 |
|---|---|
Mobile-default-signed.app |
✅ 上架就用这个,已签名的有效上架包 |
Mobile-default-unsigned.app |
❌ 未签名,不要和上面那个混淆,上传会被拒 |
symbol/release/app-symbol.zip |
符号表,用于崩溃堆栈还原,建议随版本归档 |
pack.info / pac.json |
打包元信息 |
上架只能选带
-signed的包,-unsigned.app上传会被拒。参考数据(release + 完整发布签名):构建约 11 秒,产出
build/outputs/default/Mobile-default-signed.app,3.44 MB;体积取决于rawfile/dist里放了多少东西,壳本身很小。⚠️ 只看到
-unsigned.app、没有-signed.app,不是构建失败,是签名配置没关联上,见 6.2 节末尾那条警告。
16. 注意事项
-
DevEco Studio 版本推荐 6.1。工具版本会影响 SDK,SDK 会影响真机调试。乱升版本可能导致真机装不上。
-
上架包的签名文件可以在 AGC 平台查看和下载,也可以重新申请替换(
https://developer.huawei.com/→ AGC)。但注意:.cer和.p7b可以重新下载,.p12不能(.p12只在本地)。 -
⚠️ 测试用的包名和要上线的包名可能不一致,打上架包前必须核对这部分配置。包名在
AppScope/app.json5的bundleName,仓库默认值是com.d3.app_qyxh,上架前改成自己的。三端包名彼此独立:Android / iOS 壳是
com.d3.app,鸿蒙是com.d3.app_qyxh。不要求三端一致,但每一端都必须和自己在对应平台后台注册的包名对上。 -
必须用带
-signed后缀的包上架,见 15.3。 -
⚠️ 工程路径不能含中文,否则 hvigor 直接拒绝构建。硬限制,详见第三部分。
-
build-profile.json5里的签名路径是绝对路径,换机器 / 换目录必须改,否则报找不到签名材料。 -
local.properties是本机 SDK 路径,不入库;新环境首次打开工程要让 DevEco 重新生成,或手动指向本机的sdk目录。 -
entry/src/main/resources/rawfile/dist是运行必需的 Web 产物:仓库里不带(rawfile/是空目录,dist也进了.gitignore),打包前手动放进去,见第 14 节;已经放好的那份别当无关文件删掉。 -
权限声明在
entry/src/main/module.json5,壳里声明了 3 个:
| 权限 | 类型 | 配置 |
|---|---|---|
ohos.permission.INTERNET |
普通 | 无附加配置 |
ohos.permission.GET_NETWORK_INFO |
普通 | 无附加配置 |
ohos.permission.CAMERA |
用户授权 | reason: $string:camera_permission_reason,usedScene.abilities: [EntryAbility],when: inuse |
都是普通/用户授权权限,没有申请需要华为额外审批的 ACL 受限权限,所以 5.4 申请 Profile 时不需要勾「受限权限」。
如果你的 Web 产物用不到扫码,把
ohos.permission.CAMERA一起删掉,审核时少一项要解释的东西。
- 模块配置(
module.json5):name: entry、type: entry、mainElement: EntryAbility、deviceTypes: ["phone"]、deliveryWithInstall: true、installationFree: false;abilities只有EntryAbility(exported: true,skills =entity.system.home+ohos.want.action.home);extensionAbilities有一个EntryBackupAbility(typebackup)。
第三部分 常见坑
- 工程路径不能含中文:hvigor 会直接报
00306003 Specification Limit Violation拒绝构建;目录联接(junction / 符号链接)骗不过去(hvigor 会解析真实路径),只能把工程真实拷贝到纯 ASCII 路径再打包。 - 产物名前缀跟随工程根目录名:实际产物是
<工程目录名>-default-signed.app,不要按Mobile-default-signed.app硬记;上架认带-signed后缀的那个包。 products[].signingConfig与signingConfigs[].name断开时,构建会静默降级成未签名包:不报错、不中断,只有一行WARN: No signingConfig found for product default.,最后照样BUILD SUCCESSFUL,但产物目录里只剩-unsigned.app。判断办法是看日志里有没有SignHap/SignApp任务,详见 6.2 节。仓库里的build-profile.json5不带签名配置(signingConfigs: [],products里也没有关联),克隆后必须自己补齐两处。rawfile/dist里没放 Web 产物就打包,装上去是白屏:rawfile/在仓库里是空目录,rawfile/dist还进了.gitignore,克隆下来必然没有。打包前先手动放进去,见第 14 节。- 换产物时先删旧
dist再放新的:多数打包器产出的assets/*.js带内容哈希,直接覆盖会让旧文件残留在包里,白白撑大安装包。 - 产物不要依赖外部 CDN:页面跑在离线虚拟域
https://www.harmony.local下,所有请求都被onInterceptRequest接走去读rawfile,指向外网的 importmap / external 依赖会加载失败,表现是白屏且没有任何报错。产物必须自包含。 .p12丢了无法找回:.cer/.p7b可随时从 AGC 重新下载,.p12只在本地,务必备份。build-profile.json5里的签名材料是绝对路径:换机器、换目录必须改,否则报找不到签名材料。- 真机调试不需要申请发布证书:DevEco 勾选
Automatically generate signature自动生成调试签名即可。 - 上传 AGC 时「使用场景」必须选「测试和正式上架」,选「仅测试」会导致后面做版本选取时找不到这个包。
versionCode每次上传必须递增,否则 AGC 拒收。仓库里AppScope/app.json5是1000000。