在这里插入图片描述
在这里插入图片描述

将 Flutter 鸿蒙应用发布到华为 AppGallery(应用市场),是整个开发流程的最后一步。这个过程涉及签名申请、证书配置、构建打包、应用信息填写等多个环节。本文以 E-Brufen 的实际发布经历为例,完整记录从零到上架的全流程。

1. 发布流程总览

第1步:注册华为开发者账号 → AppGallery Connect 创建应用
    ↓
第2步:生成 CSR 文件 → 申请证书 (.cer)
    ↓
第3步:创建 Provisioning Profile (.p7b)
    ↓
第4步:配置 build-profile.json5 签名信息
    ↓
第5步:填写 app.json5 应用元数据
    ↓
第6步:构建 Release HAP → 上传到 AppGallery Connect
    ↓
第7步:填写应用信息 → 提交审核

2. 第一步:AppGallery Connect 创建应用

访问 AppGallery Connect,登录华为开发者账号,创建新应用。

关键配置项:

字段 E-Brufen 的实际值
应用名称 E-Brufen
包名 com.flutter.brufen
应用类别 健康
目标平台 手机(Phone)

包名 com.flutter.brufen 是一个关键字段——它必须在以下三处保持完全一致:

  1. AppGallery Connect 的应用包名
  2. ohos/AppScope/app.json5 中的 bundleName
  3. 签名证书申请时填写的包名

任何一处不一致,都会导致签名验证失败。

3. 第二步:生成 CSR 并申请证书

3.1 什么是 CSR

CSR(Certificate Signing Request)是证书签名请求文件,包含了你的应用包名、组织信息以及公钥。鸿蒙应用签名使用的是 SHA256withECDSA 算法。

在 DevEco Studio 或命令行中生成 CSR:

# 使用 keytool 生成密钥对
keytool -genkeypair -alias "aaa" -keyalg EC -sigalg SHA256withECDSA \
  -keysize 256 -keystore firstproject.p12 -storetype PKCS12 \
  -validity 3650 -dname "CN=E-Brufen Dev, OU=Dev, O=E-Brufen, L=Shenzhen, ST=Guangdong, C=CN"

# 导出 CSR
keytool -certreq -alias "aaa" -keystore firstproject.p12 \
  -storetype PKCS12 -file firstproject.csr -sigalg SHA256withECDSA

执行后会生成两个文件:

  • firstproject.p12——密钥库(私钥),必须妥善保管,不可泄露
  • firstproject.csr——证书签名请求,用于向华为申请证书

3.2 申请调试/发布证书

.csr 文件上传到 AppGallery Connect 的"证书管理"页面。选择证书类型:

证书类型 用途 有效期
调试证书 开发阶段真机调试 1 年
发布证书 AppGallery 上架 最多 3 年

E-Brufen 申请的是发布证书,下载后得到 22.cer 文件。

4. 第三步:创建 Provisioning Profile

Provisioning Profile(.p7b 文件)将应用包名、证书、设备列表绑定在一起。在 AppGallery Connect 的"Profile 管理"页面创建:

  • 选择发布类型:Release
  • 绑定刚申请的证书
  • 填写包名:com.flutter.brufen
  • 选择设备范围(发布类型一般为全部设备)

下载后得到 123456Release.p7b

5. 第四步:配置 build-profile.json5

这是整个签名配置的核心——在 ohos/build-profile.json5 中配置签名信息:

{
  "app": {
    "signingConfigs": [
      {
        "name": "default",
        "type": "HarmonyOS",
        "material": {
          "storeFile": "D:/Flutter/firstproject/firstproject.p12",
          "storePassword": "00000019314A5E64E7AE176747817469CE44330E099BA13B5A7D6533429C0537734EAA5091705C516F",
          "keyAlias": "aaa",
          "keyPassword": "0000001994B09538837E33B686A5C7411DD18DEE804F05C29495CEFC1561BB7B2CF9F0AF915CC82BE2",
          "signAlg": "SHA256withECDSA",
          "profile": "D:/Flutter/firstproject/123456Release.p7b",
          "certpath": "D:/Flutter/firstproject/22.cer"
        }
      }
    ],
    "products": [
      {
        "name": "default",
        "signingConfig": "default",
        "compatibleSdkVersion": "6.1.0(23)",
        "runtimeOS": "HarmonyOS",
        "targetSdkVersion": "6.1.0(23)"
      }
    ],
    "buildModeSet": [
      { "name": "debug" },
      { "name": "profile" },
      { "name": "release" }
    ]
  },
  "modules": [
    {
      "name": "entry",
      "srcPath": "./entry",
      "targets": [
        {
          "name": "default",
          "applyToProducts": ["default"]
        }
      ]
    }
  ]
}

各字段说明:

字段 说明
storeFile .p12 密钥库文件的绝对路径
storePassword 密钥库密码(加密存储)
keyAlias 密钥别名,与生成 CSR 时的 -alias 一致
keyPassword 密钥密码(加密存储)
signAlg 签名算法:SHA256withECDSA
profile Provisioning Profile 文件路径
certpath 证书文件路径
compatibleSdkVersion 最低兼容 SDK 版本:6.1.0(23)
targetSdkVersion 目标 SDK 版本:6.1.0(23)

安全警告storePasswordkeyPassword 在项目 Git 仓库中是明文存储的。对于开源项目,建议将这两个值放到环境变量或本地配置文件中,并在 .gitignore 中排除。E-Brufen 作为一个个人项目,采用了本地开发直接配置的方式,但如果多人协作,务必做好密码隔离。

6. 第五步:配置应用元数据

ohos/AppScope/app.json5 中填写应用基本信息:

{
  "app": {
    "bundleName": "com.flutter.brufen",
    "vendor": "example",
    "versionCode": 1000000,
    "versionName": "1.0.0",
    "icon": "$media:1",
    "label": "$string:app_name"
  }
}

versionCode 是整数值,每次提交新版本时必须递增。$media:1 引用 AppScope/resources/base/media/1.png 作为应用图标。

对应的字符串资源在 AppScope/resources/base/element/string.json

{
  "string": [
    { "name": "app_name", "value": "E-Brufen" }
  ]
}

7. 第六步:构建 Release HAP

在项目根目录执行构建命令:

flutter build hap --release

构建产物输出到:

ohos/entry/build/default/outputs/default/
├── entry-default-unsigned.hap   # 未签名 HAP
├── entry-default-signed.hap     # 已签名 HAP(上传这个)
└── pack.info                    # 打包信息

Flutter 的鸿蒙构建工具链会自动读取 build-profile.json5 中的签名配置,在构建后对 HAP 进行签名。

8. 第七步:AppGallery Connect 上传与审核

上传 entry-default-signed.hap 到 AppGallery Connect 的"版本"页面,填写以下信息:

  1. 应用描述:介绍 E-Brufen 的功能(心理健康、白噪音、呼吸练习、情绪日记)
  2. 隐私政策:E-Brufen 是完全离线应用,不需要上传任何数据,但仍需提供隐私声明
  3. 截图:上传 3-5 张应用截图(首页、白噪音页、呼吸页、日记页)
  4. 应用分类:健康 > 心理健康

提交后等待华为审核,通常在 1-3 个工作日内完成。

9. E-Brufen 发布注意事项

从 Git 提交历史可以看到,E-Brufen 在上线前做了以下准备工作:

ab44498 chore: remove INTERNET permission (offline app), update app metadata for AppGallery release
03ea749 cleanup: remove audio assets entry from pubspec, fix EntryAbility, delete empty audio dir
891c03d feat: generate programmatic app icon, fix app.json5 reference

关键准备工作:

  1. 移除不必要的权限声明module.json5requestPermissions 设为空数组 []
  2. 清理空资源引用:删除不存在的音频资源引用,避免构建时报错
  3. 生成符合规范的应用图标:确保 AppScope/resources/base/media/entry/src/main/resources/base/media/ 中都有图标文件

10. 常见发布问题排查

问题 可能原因 解决方案
签名验证失败 包名不一致 检查三处包名是否统一
证书已过期 调试证书有效期短 检查证书类型和有效期
HAP 包名不匹配 app.json5 被修改 检查 bundleName
图标不符合规范 缺少 startWindowIcon 确保 media/icon.png 存在
审核被拒 缺少隐私声明 补充隐私政策 URL

总结

从 CSR 生成到 AppGallery 审核通过,整个发布流程需要 3-5 个工作日。最关键的环节是包名一致性和签名配置的正确性。E-Brufen 从开始开发到成功上架,经历了本地开发、调试、清理、签名的完整流程,下文将深入解析鸿蒙签名机制的技术细节。


上一篇Flutter 鸿蒙应用错误处理与优雅降级策略

下一篇鸿蒙应用签名与证书管理详解


E-Brufen Dev, Flutter & 鸿蒙开发者,项目地址:AtomGit - E‑Brufen

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐