一键发布鸿蒙5应用:AGC上架审核流程详解
一、应用发布前准备
- 配置应用签名
在entry/build-profile.json5中配置签名信息:
{
"app": {
"signingConfigs": [
{
"name": "release",
"material": {
"certpath": "signing/release.p12",
"storePassword": "yourpassword",
"keyAlias": "release",
"keyPassword": "yourpassword",
"profile": "signing/release.p7b",
"signAlg": "SHA256withECDSA",
"storeFile": "signing/release.jks"
}
}
]
}
}
2. 构建发布版本HAP
在DevEco Studio终端执行:
./gradlew assembleRelease
或使用图形界面:
点击菜单栏"Build" > "Build HAP(s)/APP(s)" > "Build Release HAP"
二、AGC控制台应用创建
- 创建新应用
// 伪代码:模拟AGC应用创建API调用
async function createAGCApp(appInfo: {
appName: string,
packageName: string,
category: string,
defaultLanguage: string
}) {
const response = await fetch('https://connect-api.cloud.huawei.com/api/v1/apps', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization':Bearer ${await getAGCToken()}
},
body: JSON.stringify(appInfo)
});
return await response.json();
}
// 示例调用
createAGCApp({
appName: "我的鸿蒙应用",
packageName: "com.example.myharmonyapp",
category: "工具",
defaultLanguage: "zh-CN"
});
三、应用信息配置
- 基本信息配置
在AGC控制台填写:
应用名称(中英文)
应用分类
默认语言
应用简介(200字符内)
应用描述(2000字符内)
2. 隐私政策配置
创建privacy.html并上传:
隐私政策
最后更新时间:2023年10月
<h2>1. 信息收集</h2>
<p>我们可能会收集以下信息:</p>
<ul>
<li>设备信息(型号、操作系统版本)</li>
<li>使用数据(功能使用情况)</li>
</ul>
<h2>2. 信息使用</h2>
<p>收集的信息将用于:</p>
<ul>
<li>改进应用功能</li>
<li>分析用户行为</li>
</ul>
四、应用包上传与版本管理
1. 上传HAP文件
使用AGC API上传示例:
async function uploadHAPFile(appId: string, filePath: string) {
const formData = new FormData();
formData.append('file', new Blob([await fs.readFile(filePath)]));
const response = await fetch(
https://connect-api.cloud.huawei.com/api/v1/apps/${appId}/packages,
{
method: 'POST',
headers: {
'Authorization': Bearer ${await getAGCToken()}
},
body: formData
}
);
return await response.json();
}
2. 配置版本信息
async function setVersionInfo(appId: string, version: {
versionCode: number,
versionName: string,
releaseNotes: Record<string, string>
}) {
const response = await fetch(
https://connect-api.cloud.huawei.com/api/v1/apps/${appId}/versions,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': Bearer ${await getAGCToken()}
},
body: JSON.stringify(version)
}
);
return await response.json();
}
五、审核前自检工具实现
- 自动化检查脚本
创建precheck.ets:
import bundleManager from '@ohos.bundle.bundleManager';
import permission from '@ohos.permission';
export class AppPublishChecker {
// 检查必要权限声明
static async checkRequiredPermissions(): Promise<string[]> {
const requiredPerms = [
permission.Permission.INTERNET,
permission.Permission.READ_MEDIA,
permission.Permission.WRITE_MEDIA
];
const missingPerms: string[] = [];
const bundleInfo = await bundleManager.getBundleInfoForSelf();
for (const perm of requiredPerms) {
if (!bundleInfo.reqPermissions.includes(perm)) {
missingPerms.push(perm);
}
}
return missingPerms;
}
// 检查隐私政策链接
static async checkPrivacyPolicy(): Promise
try {
const httpRequest = http.createHttp();
const response = await httpRequest.request(
'https://www.yourdomain.com/privacy.html',
{ method: 'HEAD' }
);
return response.responseCode === 200;
} catch {
return false;
}
}
// 检查应用图标
static async checkAppIcons(): Promise
const bundleInfo = await bundleManager.getBundleInfoForSelf();
return !!bundleInfo.icons.length;
}
// 运行全部检查
static async runFullCheck(): Promise<{
passed: boolean,
details: Record<string, any>
}> {
const results = {
permissions: await this.checkRequiredPermissions(),
privacyPolicy: await this.checkPrivacyPolicy(),
icons: await this.checkAppIcons()
};
return {
passed: results.permissions.length === 0 &&
results.privacyPolicy &&
results.icons,
details: results
};
}
}
六、一键发布脚本实现
- 完整发布流程脚本
创建publish.ets:
import fs from '@ohos.file.fs';
import http from '@ohos.net.http';
export class AppPublisher {
private static readonly AGC_API = 'https://connect-api.cloud.huawei.com';
// 获取AGC访问令牌
private static async getAGCToken(): Promise
const auth = agconnect.auth();
const user = auth.currentUser;
if (!user) {
throw new Error('请先登录AGC账号');
}
return await user.getToken();
}
// 上传HAP文件
private static async uploadPackage(appId: string, hapPath: string): Promise
const token = await this.getAGCToken();
const httpRequest = http.createHttp();
try {
const file = await fs.open(hapPath, fs.OpenMode.READ_ONLY);
const fileStat = await fs.stat(hapPath);
const fileContent = await fs.read(file.fd, { length: fileStat.size });
await fs.close(file.fd);
const response = await httpRequest.request(
`${this.AGC_API}/api/v1/apps/${appId}/packages`,
{
method: 'POST',
header: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'multipart/form-data'
},
extraData: {
'file': {
filename: hapPath.split('/').pop(),
contentType: 'application/octet-stream',
data: fileContent
}
}
}
);
return JSON.parse(response.result);
} catch (error) {
console.error('上传HAP失败:', error);
throw error;
}
}
// 提交审核
private static async submitForReview(appId: string, versionId: string): Promise
const token = await this.getAGCToken();
const httpRequest = http.createHttp();
try {
const response = await httpRequest.request(
`${this.AGC_API}/api/v1/apps/${appId}/versions/${versionId}/submit`,
{
method: 'POST',
header: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);
return JSON.parse(response.result);
} catch (error) {
console.error('提交审核失败:', error);
throw error;
}
}
// 一键发布
static async publish(appId: string, hapPath: string): Promise
try {
console.log('开始应用发布流程...');
// 1. 运行预检查
const precheck = await AppPublishChecker.runFullCheck();
if (!precheck.passed) {
console.error('预检查未通过:', precheck.details);
return false;
}
// 2. 上传HAP
console.log('上传HAP文件中...');
const uploadResult = await this.uploadPackage(appId, hapPath);
console.log('上传成功,包ID:', uploadResult.packageId);
// 3. 提交审核
console.log('提交审核中...');
const reviewResult = await this.submitForReview(appId, uploadResult.versionId);
console.log('审核提交成功,跟踪ID:', reviewResult.trackingId);
return true;
} catch (error) {
console.error('发布流程出错:', error);
return false;
}
}
}
七、审核状态监控
- 审核状态查询组件
@Entry
@Component
struct ReviewStatusPage {
@State appId: string = '';
@State trackingId: string = '';
@State status: string = 'loading';
@State lastCheck: string = '';
private timer: number = 0;
onPageShow() {
const params = router.getParams();
if (params) {
this.appId = params.appId;
this.trackingId = params.trackingId;
this.checkStatus();
this.startPolling();
}
}
onPageHide() {
this.stopPolling();
}
startPolling() {
this.timer = setInterval(() => {
this.checkStatus();
}, 300000); // 每5分钟检查一次
}
stopPolling() {
if (this.timer) {
clearInterval(this.timer);
}
}
async checkStatus() {
try {
const httpRequest = http.createHttp();
const token = await agconnect.auth().currentUser?.getToken();
const response = await httpRequest.request(
`https://connect-api.cloud.huawei.com/api/v1/apps/${this.appId}/reviews/${this.trackingId}`,
{
method: 'GET',
header: {
'Authorization': `Bearer ${token}`
}
}
);
const result = JSON.parse(response.result);
this.status = result.status;
this.lastCheck = new Date().toLocaleString();
} catch (error) {
console.error('获取审核状态失败:', error);
this.status = 'error';
}
}
build() {
Column({ space: 20 }) {
Text('应用审核状态')
.fontSize(24)
.fontWeight(FontWeight.Bold)
Text(`应用ID: ${this.appId}`)
.fontSize(16)
Text(`跟踪ID: ${this.trackingId}`)
.fontSize(16)
Divider()
if (this.status === 'loading') {
LoadingProgress()
} else {
Text(`状态: ${this.getStatusText()}`)
.fontSize(20)
.fontColor(this.getStatusColor())
Text(`最后检查: ${this.lastCheck}`)
.fontSize(14)
.fontColor(Color.Gray)
}
Button('刷新状态')
.width(200)
.onClick(() => {
this.checkStatus();
})
}
.width('100%')
.height('100%')
.padding(20)
}
private getStatusText(): string {
const statusMap: Record<string, string> = {
'pending': '审核中',
'approved': '审核通过',
'rejected': '审核未通过',
'error': '获取状态失败'
};
return statusMap[this.status] || this.status;
}
private getStatusColor(): Color {
const colorMap: Record<string, Color> = {
'pending': Color.Blue,
'approved': Color.Green,
'rejected': Color.Red,
'error': Color.Orange
};
return colorMap[this.status] || Color.Black;
}
}
八、常见审核问题处理
-
审核拒绝常见原因及解决方案
拒绝原因 解决方案 代码示例
隐私政策不完整 补充隐私政策内容 [见第三章隐私政策配置]
权限声明不足 添加缺失权限声明 module.json5中添加reqPermissions
应用图标缺失 提供多尺寸应用图标 确保resources/base/media包含图标文件
功能描述不符 修改应用描述 更新AGC控制台的应用描述 -
快速修复与重新提交
// 在AppPublisher中添加
static async resubmitAfterRejection(
appId: string,
trackingId: string,
fixes: {
updatedHapPath?: string,
updatedPrivacyPolicy?: string,
updatedDescription?: string
}
): Promise{
try {
// 1. 更新应用信息
if (fixes.updatedPrivacyPolicy || fixes.updatedDescription) {
await this.updateAppInfo(appId, {
privacyPolicy: fixes.updatedPrivacyPolicy,
description: fixes.updatedDescription
});
}// 2. 上传新版本(如果有)
if (fixes.updatedHapPath) {
await this.uploadPackage(appId, fixes.updatedHapPath);
}// 3. 重新提交审核
const response = await http.createHttp().request(
${this.AGC_API}/api/v1/apps/${appId}/reviews/${trackingId}/resubmit,
{
method: 'POST',
header: {
'Authorization':Bearer ${await this.getAGCToken()}
}
}
);return JSON.parse(response.result).success;
} catch (error) {
console.error('重新提交失败:', error);
return false;
}
}
九、发布后管理 -
版本回滚实现
// 在AppPublisher中添加
static async rollbackVersion(appId: string, versionCode: number): Promise{
try {
const response = await http.createHttp().request(
${this.AGC_API}/api/v1/apps/${appId}/versions/${versionCode}/rollback,
{
method: 'POST',
header: {
'Authorization':Bearer ${await this.getAGCToken()}
}
}
);return JSON.parse(response.result).success;
} catch (error) {
console.error('版本回滚失败:', error);
return false;
}
} -
分阶段发布控制
// 在AppPublisher中添加
static async stagedRollout(
appId: string,
versionCode: number,
percentage: number
): Promise{
if (percentage < 1 || percentage > 100) {
throw new Error('百分比必须在1-100之间');
}
try {
const response = await http.createHttp().request(
${this.AGC_API}/api/v1/apps/${appId}/versions/${versionCode}/rollout,
{
method: 'POST',
header: {
'Authorization': Bearer ${await this.getAGCToken()},
'Content-Type': 'application/json'
},
extraData: JSON.stringify({ percentage })
}
);
return JSON.parse(response.result).success;
} catch (error) {
console.error('分阶段发布设置失败:', error);
return false;
}
}
总结
通过本文的学习,你已经掌握了鸿蒙5应用通过AGC一键发布的完整流程:
前期准备:签名配置与HAP打包
应用创建:AGC控制台应用信息配置
审核自检:自动化检查工具实现
一键发布:完整发布脚本开发
状态监控:审核进度实时跟踪
发布管理:版本控制与分阶段发布
AGC提供的发布流程为开发者带来了:
高效发布:简化应用上架流程
智能审核:自动化检查提高通过率
灵活控制:版本管理和分阶段发布
全面监控:实时跟踪审核状态
在实际项目开发中,你还可以进一步探索:
与CI/CD流水线的深度集成
自动化测试与发布的结合
多环境发布策略管理
应用审核数据分析与优化

浙公网安备 33010602011771号