HarmonyOS 应用准备提交 AppGallery Connect 时,最危险的往往不是某一个字段不会填,而是工程、安装包、平台资料和用户可见文案分别正确,组合起来却互相矛盾。例如,应用介绍写“完全离线”,module.json5 却声明了网络权限;平台勾选平板和 2in1,应用虽然能安装,但页面仍永远走手机底部导航;AppGallery 上传了新版图标,软件包中的分层图标还是旧素材;版本名称看起来相同,真正参与升级判断的 versionCode 却没有递增。
本文以真实的“中国方言题库”HarmonyOS 工程为复查对象。当前源码位于 D:\\huawei\\one11,应用身份为 com.example.one11,versionName 为 1.0.2,versionCode 为 10000003,目标设备包含 phone、tablet、2in1。项目采用 ArkTS、ArkUI 和 Stage 模型,题库主体数据保存在应用内,本地学习记录由数据服务管理;听音题优先创建离线 TTS 引擎,失败后会尝试在线 TTS,因此工程声明了 ohos.permission.INTERNET。
这组事实决定了复查结论:它可以描述为“题库与学习记录以本地能力为主,核心答题流程不依赖账号和业务服务器”,但不能在未补充限定语时写成“完全离线、绝不联网”。发布资料必须忠于代码,而不是忠于最省事的宣传口径。
本文只记录可由当前源码、资源和本地配置复核的事实。没有登录 AppGallery Connect 回读在线字段,也没有把“本地复查通过”写成“平台审核通过”。发布状态、审核结论、下载量和平台数据均不在本文虚构。

一、先把发布复查定义成一致性验证
AppGallery 发布并不是单一动作,而是四份事实的汇合:
复查不是把四份表格分别打勾,而是逐项寻找跨层冲突。最有用的问题不是“这里填了吗”,而是:
同一个结论,能否同时被源码、包、AGC 页面和用户界面证明?
本文采用的唯一核验标记是:
发布复查不是寻找一个正确字段,而是消除四份事实之间的冲突
它也可以作为发布记录、草稿回读或流水线审计时的正文定位标记。
二、第一道门:包名、应用 ID 和版本必须指向同一对象
2.1 源码中的应用身份
当前 AppScope/app.json5 的关键字段如下:
{
"app": {
"bundleName": "com.example.one11",
"vendor": "JiaWeiKang",
"versionCode": 10000003,
"versionName": "1.0.2",
"icon": "$media:layered_image",
"label": "$string:app_name"
}
}
其中,bundleName 是识别应用身份的核心字段;versionName 是用户可见版本;versionCode 是整数版本序号。发布复查时不能只盯着 1.0.2,因为平台判断升级关系时还要依赖递增的版本序号。
本次队列资料中记录的应用 ID 为 6917605760559571316,包名为 com.example.one11。由于本文没有登录 AGC 在线页面,能得出的结论仅是“本地队列和源码包名一致”;仍需在真正提交前进入目标应用,重新核对 APP ID、包名和租户账号,避免在相似名称的应用下上传错误软件包。
2.2 为什么版本复查要同时看两个数字
推荐为每次候选包留下这样一条记录:
appName = 中国方言题库
bundleName = com.example.one11
versionName = 1.0.2
versionCode = 10000003
sourceCommit = 当前候选源码提交
packageHash = 构建产物哈希
如果只保存文件名,例如 entry-default-signed.app,几天后很难证明它对应哪次修复。最稳妥的方式是在构建完成后再从实际产物或 AGC 包解析结果回读版本,而不是仅根据源码文件推断上传成功。
2.3 上传新包不等于版本已切换
发布后台常见的状态至少包括:
- 软件包已经上传;
- 软件包解析成功;
- 当前版本已选择该软件包;
- 当前版本信息已保存;
- 已提交审核;
- 预审核中;
- 审核中;
- 已上架或被驳回。
这些状态不能互相替代。上传新包之后,要回到版本页面确认当前版本真正绑定的是最新候选包,并通过版本号、上传时间、文件大小或包解析信息完成回读。本文没有执行该在线步骤,因此不会宣称已经替换或提交任何版本。
三、第二道门:设备类型不是三个勾选框
当前 entry/src/main/module.json5 声明:
"deviceTypes": [
"phone",
"tablet",
"2in1"
]
这意味着发布资料、截图组和运行验证都应覆盖这三类设备范围。平台勾选设备类型时必须与包能力一致;反过来,包声明支持某设备,也不能只凭“能安装”就认定适配完成。
3.1 当前源码已经做了哪些多设备准备
EntryAbility.ets 注册了断点系统,并读取顶部系统避让区和底部导航指示区:
UserDataManager.init(this.context)
BreakpointSystem.register()
窗口创建后,代码监听 avoidAreaChange,把避让高度写入 AppStorage。Index.ets 再通过:
private bottomSafePadding(): number {
return Math.max(
Sizes.BOTTOM_NAV_MIN_PADDING,
this.getUIContext().px2vp(this.navigationIndicatorHeightPx)
)
}
保证底部导航至少保留既定安全距离。这个实现对手机手势区和不同系统导航模式是有价值的真实适配点。
HomePage.ets 还通过页面宽度决定题库区域是否采用三列网格:
private useGridLayout(): boolean {
return this.currentBp === 'lg' && this.pageWidth >= 700
}
因此,首页内部已经具备大宽度布局分支。
3.2 真实源码里仍有一个必须列入复查的分支问题
Index.ets 的主结构当前写成:
if (this.currentBp === 'sm' ||
this.currentBp === 'md' ||
this.currentBp === 'lg') {
// 手机模式:底部导航
} else {
// 平板/折叠模式:侧边导航 + 内容区
}
如果断点系统只会产生 sm、md、lg,那么 else 侧边导航分支实际上不可达。也就是说,模块声明支持平板和 2in1,并不自动证明平板一定显示侧边导航。发布复查必须把“设备声明”和“运行时分支”连起来验证:
| 手机竖屏 | 底部导航、手势区避让 | 已有底部安全区计算 |
| 手机横屏/小窗 | 文本不溢出、操作可达 | 需运行复核 |
| 平板横竖屏 | 内容区利用宽度 | 首页有大宽度网格 |
| 2in1 调整窗口 | 导航结构随断点变化 | 侧边导航条件需重点复核 |
| 系统深色模式 | 锁定浅色后局部不反色 | EntryAbility 有固定色彩模式逻辑 |
所以,发布资料中可以如实写“支持 phone、tablet、2in1”,但提交前应完成真机或模拟器的窗口缩放验证,不能只依据 deviceTypes 数组。
四、第三道门:离线声明必须和权限、Kit 以及降级路径一致
4.1 工程为什么存在网络权限
当前模块声明了:
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
进一步检查 PracticePage.ets 可以找到真实原因:
this.ttsEngine = await textToSpeech.createEngine({
language: 'zh-CN',
person: 0,
online: 0
})
离线 TTS 创建失败时,代码会尝试:
this.ttsEngine = await textToSpeech.createEngine({
language: 'zh-CN',
person: 0,
online: 1
})
因此,“完全不使用网络”与当前代码不一致。更准确的发布描述应该是:
题库内容、答题、错题、收藏、笔记和学习记录以本地数据为主;听音题优先使用离线语音能力,在设备离线语音不可用时可能尝试在线语音能力。语音不可用不会阻断题目文字内容与答题流程。
这个表述同时对应了权限声明、TTS 创建策略和页面降级行为。
4.2 “本地主流程”与“完全离线”不是同义词
可以用三层模型审查网络声明:
| 核心业务数据 | 题库是否必须从服务器下载 | 否,题目在本地源码数据中 |
| 用户学习数据 | 是否依赖账号或云端同步 | 当前源码以本地管理为主 |
| 辅助能力 | 是否存在联网 Kit 或在线降级 | 有,TTS 在线兜底 |
所以,“无需登录即可完成核心练习”是可核验的;“永不联网”则不是。
4.3 隐私声明不应只复制权限名称
隐私资料应解释:
华为隐私保护文档强调公开透明、数据最小化、用户控制、安全和本地优先。对本项目而言,最关键的是不要因为题库主体在本地,就忽略在线 TTS 这一真实网络路径;也不要在没有源码证据时声称上传了用户答案或设备信息。
五、第四道门:图标必须同时核对包内资源与 AGC 素材
当前 app.json5 和 module.json5 都指向 $media:layered_image,分层定义为:
{
"layered-image": {
"background": "$media:background",
"foreground": "$media:foreground"
}
}
工程在 AppScope/resources/base/media 和 entry/src/main/resources/base/media 中都保存了背景、前景和分层定义。复查不能只看到文件存在,还要检查:
- AppScope 图标与 entry 图标是否来自同一设计;
- 背景是否为明确、不依赖透明像素的设计;
- 前景是否清晰,是否被重复裁圆角;
- Launcher、安装页、启动窗口和 AppGallery 展示是否一致;
- 浅色、深色背景下是否仍能辨认;
- AGC 上传图标是否与软件包中的图标一致。
华为当前的应用图标配置文档明确要求包内正确预置图标,且 AGC 上传图标应与软件包图标一致;图标不应模糊、拉伸或压缩。项目还单独配置了 startWindowIcon,因此启动窗口也应纳入一致性截图,而不能只查看桌面图标。
六、第五道门:截图不是装饰图,而是当前版本的可验证证据
该项目历史复盘已经记录过截图问题:旧截图出现标题裁切、模拟器外框、虚拟题量和横竖屏混用。这个经验直接转化为发布门槛:
6.1 同一设备组的基本规则
- 使用当前最新候选包;
- 同一组尺寸一致、方向一致;
- 不混入旧版本虚拟题量;
- 不保留模拟器外框、调试悬浮窗或敏感信息;
- 至少展示三个不同核心功能;
- 标题、状态栏、底部导航和主要按钮完整可见。
6.2 中国方言题库适合展示的真实页面
推荐截图组合:
截图文字必须和实际数据源一致。当前工程曾因题量显示与实际内容不一致返工,因此不能为了“看起来丰富”在详情页素材中写入源码无法支撑的数字。
七、把复查做成可执行流水线

7.1 步骤一:冻结候选源码
先确认这次发布对应的源码状态,记录提交、分支和变更范围。工作区有无关改动时,不要把它们误打入候选包,也不要为了清理环境而覆盖他人的修改。
7.2 步骤二:读取身份和能力清单
建立机器可读清单:
{
"bundleName": "com.example.one11",
"versionName": "1.0.2",
"versionCode": 10000003,
"deviceTypes": ["phone", "tablet", "2in1"],
"permissions": ["ohos.permission.INTERNET"],
"networkReason": "在线 TTS 兜底",
"coreDataMode": "本地题库与本地学习记录"
}
这个清单不是平台填写值的替代品,而是所有平台字段的对照基线。
7.3 步骤三:构建并验证实际产物
推荐使用项目已有构建链路生成候选 APP,并记录:
构建命令 实际执行的 assembleApp/assembleHap 命令
构建结果 passed / failed
产物路径 实际候选包
文件大小 构建后读取
哈希 SHA-256
签名状态 仅记录是否有效,不记录密码和证书私密信息
本文没有在本次写作过程中重新执行完整构建、安装和卸载,所以这些结果不能被写成“已通过”。发布人员应在正式提交前补齐实际证据。
7.4 步骤四:运行安装—启动—核心流程—卸载冒烟
至少覆盖:
安装候选包
首次启动进入 SplashPage
跳转 Index
进入题库
完成一道普通题
触发一题听音题
网络不可用时验证降级
收藏或记录学习进度
退出并重新进入
卸载应用
HarmonyOS 审核关注兼容性和运行稳定性。仅有编译成功不能证明没有启动崩溃、白屏、路由失败、卡死或权限循环。
7.5 步骤五:回读 AGC 当前版本
在平台中逐项回读:
- 当前应用名称、APP ID、包名;
- 当前版本绑定的软件包;
- 版本名和版本号;
- 设备类型;
- 语言、分类、标签和更新说明;
- 图标与每个设备组截图;
- 隐私声明、权限用途、SDK 列表;
- 付费、登录、广告、账号、联网等实际情况;
- 分发国家和地区;
- 内容分级与资质。
遇到短信、验证码、扫码、安全验证、法律确认或最终不可逆提交,应停止自动化,由账号持有人完成确认。
八、用“差异表”替代凭感觉复查

下面这张表适合直接放进版本发布记录:
| 包名 | com.example.one11 | 同包名目标应用 | 通常不展示 | 本地一致 |
| 版本 | 1.0.2 / 10000003 | 绑定同版本包 | 关于页需一致 | 待平台回读 |
| 设备 | phone/tablet/2in1 | 勾选同范围 | 描述不夸大 | 需运行适配 |
| 网络 | INTERNET | 如实声明 | 本地主流程+TTS 可能联网 | 不能写完全离线 |
| 图标 | layered_image | 与包内一致 | 启动/关于一致 | 待平台目视 |
| 截图 | 当前真实 UI | 各设备组上传 | 不出现虚拟数据 | 待候选包重拍 |
| 数据 | 题库与记录本地为主 | 隐私标签如实填 | 可说明无需账号 | 需覆盖清除路径 |
差异表的价值在于,它会主动暴露“某一列没有证据”的位置。例如,源码声明三类设备,但没有平板截图;有网络权限,但应用介绍写完全离线;平台上传了新图标,但包内仍是旧资源。只看单列时这些问题都不明显。
九、当前工程复查得到的真实结论
9.1 已能从源码确认
- 包名为 com.example.one11;
- 用户可见版本为 1.0.2;
- 整数版本号为 10000003;
- 设备类型声明为 phone、tablet、2in1;
- 应用入口为 Stage 模型 EntryAbility;
- 首屏加载 pages/SplashPage;
- 应用使用本地题库和本地学习数据服务;
- 底部安全区已接入窗口避让区;
- 首页存在大宽度网格布局;
- 模块声明了网络权限;
- 听音题离线 TTS 失败后会尝试在线 TTS;
- TTS 失败不会阻断文字答题弹窗;
- AppScope 与 entry 均使用分层图标配置。
9.2 当前仍需要发布前确认
- 实际 APP 候选包是否由当前源码构建;
- 候选包签名和安装是否有效;
- versionCode 是否高于平台现有线上包;
- AGC 当前版本是否真正绑定最新候选包;
- 三类设备在运行时是否都达到可用布局;
- 侧边导航分支是否符合断点系统实际输出;
- 包内图标与 AGC 图标是否视觉一致;
- 截图是否来自当前版本并覆盖真实功能;
- 隐私声明是否解释在线 TTS 兜底;
- 断网、无离线 TTS、重复点击和窗口缩放是否稳定;
- 安装、启动、核心流程和卸载冒烟是否通过。
9.3 不能据此宣称
- 不能宣称本次已登录 AGC 并完成在线复查;
- 不能宣称已经提交审核或通过审核;
- 不能宣称完全离线;
- 不能宣称所有平板和 2in1 布局已经实机通过;
- 不能宣称任何下载量、PV、点赞、收藏或平台推荐结果。
十、一个适合团队落地的发布门禁
可以把发布门禁拆成五个明确结果:
Gate A Identity
包名、APP ID、版本名、版本号一致
Gate B Capability
设备、权限、Kit、数据路径与资料一致
Gate C Experience
安装、启动、核心流程、返回、异常、卸载通过
Gate D Material
图标、截图、文案、隐私、分类、分级一致
Gate E Platform
最新候选包已选中并保存,提交状态已回读
每个 Gate 只能记录 passed、failed 或 not run。不要使用“应该没问题”“以前通过过”“大概是最新版”这类不可复核表达。
十一、常见误区与修正
误区一:版本名没变也能覆盖上传
修正:同时核对 versionName 和递增的 versionCode,再从平台解析信息回读。
误区二:声明设备类型就等于完成适配
修正:把每种设备映射到布局分支、截图组和冒烟用例。当前工程尤其要复核侧边导航分支的可达性。
误区三:本地题库就可以写完全离线
修正:继续搜索权限、Kit、在线降级、统计 SDK、广告、推送和账号能力。当前工程存在在线 TTS 兜底,因此必须限定描述。
误区四:AGC 图标好看就够了
修正:平台图标、AppScope、entry、Launcher 和启动窗口一起核对,避免包内外不一致。
误区五:旧截图只是 UI 相同,继续用也没关系
修正:截图中的数据、版本、状态栏、安全区和内容都可能过期。应从当前候选包重新采集。
误区六:上传成功就是发布成功
修正:上传、解析、选包、保存、提交、预审、审核和上架是不同状态,每一步都应回读。
十二、结语
中国方言题库的发布复查揭示了一个很典型的工程事实:应用主体确实是本地题库,学习记录也以本地为主,但听音能力存在在线 TTS 兜底;模块确实声明支持三类设备,首页也有宽屏网格,但主导航的侧边分支仍要结合断点输出验证。把这些差异写清楚,比给应用贴一个“离线、多端、已适配”的标签更有价值。
真正可靠的 AppGallery 发布流程,不是把后台表单填满,而是让源码、候选包、平台字段和用户承诺形成闭环。只有当每个结论都能回到真实文件、真实包、真实页面和真实运行证据时,发布复查才算完成。
参考资料
https://developer.huawei.com/consumer/cn/appgallery/
https://developer.huawei.com/consumer/cn/app/submit/
https://developer.huawei.com/consumer/cn/doc/doccenter-architecture/bpta-app-privacy-protection
https://developer.huawei.com/consumer/cn/doc/doccenter-feature-dev/bpta-app-icon-configuration
https://developer.huawei.com/consumer/cn/doc/app/50104-03
https://developer.huawei.com/consumer/cn/doc/app/50104-02
- 华为开发者联盟:应用市场接入与应用上架
- 华为开发者联盟:提交 HarmonyOS 应用
- HarmonyOS 开发者:应用隐私保护
- HarmonyOS 开发者:应用图标配置与开发
- 华为应用市场审核指南:兼容性与运行稳定性相关条款
- 华为应用市场审核指南:恶意软件及行为相关条款
创作声明:本文基于真实 HarmonyOS 工程进行源码复查,内容由作者整理,并使用 AI 辅助完成结构梳理与文字校对;所有源码能力、配置字段和未执行项均按可复核证据描述。




