HarmonyOS开发:AppGallery Connect应用市场集成
HarmonyOS开发:AppGallery Connect应用市场集成
📌 核心要点:AppGallery Connect是华为为开发者提供的一站式服务平台,从账号注册到服务集成,从应用配置到数据分析,搞懂AGC就等于拿到了HarmonyOS应用上架的入场券。
背景与动机
你写了一个HarmonyOS应用,跑在模拟器上没问题,跑在真机上也没问题,然后呢?就放在自己手机上用?
应用开发完了,下一步就是上架。而HarmonyOS应用上架的唯一官方渠道就是华为应用市场(AppGallery)。想上架,你就绕不开AppGallery Connect(简称AGC)这个平台。
AGC不只是一个"上传APP包"的地方。它是一整套开发者服务生态——推送、分析、认证、云数据库、远程配置……你开发中遇到的很多"后端需求",AGC都帮你解决了。不用自己搭服务器,不用自己写接口,开箱即用。
但问题来了:AGC的功能太多了,很多开发者第一次进去直接懵圈。账号怎么注册?资质怎么认证?项目怎么创建?服务怎么集成?一个环节卡住,后面全走不通。
这篇文章,就是帮你把AGC从注册到集成的完整链路捋清楚。
核心原理
AGC整体架构
先看清楚AGC的全貌,别上来就瞎点。
graph TB
A[AppGallery Connect] --> B[开发者账号管理]
A --> C[项目管理]
A --> D[应用管理]
A --> E[核心服务]
B --> B1[个人开发者]
B --> B2[企业开发者]
C --> C1[项目创建]
C --> C2[团队协作]
C --> C3[权限管理]
D --> D1[应用信息配置]
D --> D2[版本管理]
D --> D3[应用发布]
E --> E1[推送服务 Push Kit]
E --> E2[分析服务 Analytics Kit]
E --> E3[认证服务 Auth Service]
E --> E4[云数据库 CloudDB]
E --> E5[远程配置 Remote Config]
E --> E6[崩溃服务 Crash Service]
classDef mainStyle fill:#FF6B35,stroke:#D4551F,color:#fff,font-weight:bold
classDef subStyle fill:#4ECDC4,stroke:#3BA99C,color:#fff
classDef leafStyle fill:#45B7D1,stroke:#2E8EA8,color:#fff
classDef serviceStyle fill:#96CEB4,stroke:#6DAF8E,color:#fff
class A mainStyle
class B,C,D,E subStyle
class B1,B2,C1,C2,C3,D1,D2,D3 leafStyle
class E1,E2,E3,E4,E5,E6 serviceStyle
整个AGC的核心逻辑就三层:
- 账号层:你是谁?个人还是企业?资质过不过关?
- 项目层:你的应用属于哪个项目?团队里谁有权限?
- 服务层:你的应用需要哪些AGC服务?推送?分析?云存储?
三层之间的关系是:账号→创建项目→项目下挂应用→应用启用服务。搞清楚这个链路,就不会迷路。
AGC服务集成流程
集成一个AGC服务,标准流程长这样:
graph LR
A[AGC控制台启用服务] --> B[下载agconnect-services.json]
B --> C[配置项目级build-profile]
C --> D[添加服务SDK依赖]
D --> E[初始化SDK]
E --> F[调用服务API]
classDef stepStyle fill:#FF6B35,stroke:#D4551F,color:#fff,font-weight:bold
classDef fileStyle fill:#4ECDC4,stroke:#3BA99C,color:#fff
class A,C,D,E,F stepStyle
class B fileStyle
关键点在哪?在agconnect-services.json这个文件。它是AGC的配置中心,里面包含了你的应用ID、项目ID、各服务的配置参数。没有这个文件,SDK初始化都过不去。
代码实战
基础用法:开发者账号注册与项目创建
这部分虽然不是写代码,但比写代码更重要。账号搞不定,后面啥也干不了。
第一步:注册华为开发者账号
打开华为开发者联盟,点击注册。个人开发者用身份证就行,企业开发者需要营业执照。
个人开发者认证材料:
- 身份证正反面照片
- 手持身份证照片
- 真实姓名和手机号
企业开发者认证材料:
- 营业执照扫描件
- 企业对公账户信息
- 法人身份证信息
认证审核一般1-3个工作日。别卡着项目节点才去认证,提前搞。
第二步:创建项目和应用
认证通过后,进入AGC控制台,创建项目→创建应用。
这里有个坑:项目名和应用名不是一回事。一个项目可以包含多个应用(比如免费版和付费版),项目是管理维度,应用是发布维度。
第三步:配置应用信息
创建应用后需要填写:
- 应用包名(必须和代码里的一致)
- 应用类型(APP或快应用)
- SHA256证书指纹(调试证书和发布证书都要配)
进阶用法:AGC核心服务SDK集成
下面以推送服务(Push Kit)为例,演示完整的AGC服务集成流程。
1. 下载配置文件
在AGC控制台→项目设置→常规,下载agconnect-services.json文件,放到项目的entry/src/main/resources/rawfile/目录下。
2. 配置项目构建信息
// entry/oh-package.json5 添加推送服务依赖
{
"name": "entry",
"version": "1.0.0",
"description": "HarmonyOS应用",
"main": "",
"author": "",
"license": "",
"dependencies": {
// 推送服务SDK
"@hms.core.push": "^6.12.0",
// 认证服务SDK(如果需要)
"@hms.core.authentication": "^6.12.0",
// 分析服务SDK
"@hms.core.analytics": "^6.12.0"
}
}
3. 初始化AGC SDK
// entry/src/main/ets/entryability/EntryAbility.ets
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { hilog } from '@kit.PerformanceAnalysisKit';
// 导入AGC初始化模块
import { agConnect } from '@hms.core.agconnect';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(0x0000, 'EntryAbility', 'onCreate');
// 初始化AGC——这一步必须在所有AGC服务调用之前完成
try {
agConnect.initialize(this.context);
hilog.info(0x0000, 'AGC', 'AGC初始化成功');
} catch (error) {
hilog.error(0x0000, 'AGC', `AGC初始化失败: ${JSON.stringify(error)}`);
}
}
onWindowStageCreate(windowStage: window.WindowStage): void {
hilog.info(0x0000, 'EntryAbility', 'onWindowStageCreate');
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
hilog.error(0x0000, 'EntryAbility', `加载失败: ${JSON.stringify(err)}`);
return;
}
hilog.info(0x0000, 'EntryAbility', '加载成功');
});
}
}
4. 调用推送服务获取Push Token
// entry/src/main/ets/pages/PushPage.ets
import { pushService } from '@hms.core.push';
import { hilog } from '@kit.PerformanceAnalysisKit';
@Entry
@Component
struct PushPage {
@State pushToken: string = '未获取';
@State message: string = '等待推送...';
// 获取Push Token
async getToken() {
try {
// 先检查推送服务是否可用
const isAvailable = await pushService.isAvailable();
if (!isAvailable) {
this.pushToken = '推送服务不可用';
return;
}
// 获取Push Token
const token = await pushService.getToken();
this.pushToken = token;
hilog.info(0x0000, 'Push', `获取Token成功: ${token}`);
// 实际项目中,需要把Token上报到你的服务器
// this.reportTokenToServer(token);
} catch (error) {
this.pushToken = `获取失败: ${error.message}`;
hilog.error(0x0000, 'Push', `获取Token失败: ${JSON.stringify(error)}`);
}
}
build() {
Column({ space: 20 }) {
Text('Push Kit 集成示例')
.fontSize(24)
.fontWeight(FontWeight.Bold)
Text(`Push Token: ${this.pushToken}`)
.fontSize(14)
.fontColor('#666666')
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
Button('获取Push Token')
.width('80%')
.onClick(() => this.getToken())
Text(this.message)
.fontSize(16)
.margin({ top: 20 })
}
.width('100%')
.height('100%')
.padding(20)
.justifyContent(FlexAlign.Center)
}
}
完整示例:集成分析服务+推送服务+远程配置
一个真实项目通常不会只用一个AGC服务。下面这个示例把分析、推送、远程配置三个服务串起来,展示多服务协同的完整流程。
// entry/src/main/ets/utils/AGCManager.ets
// AGC服务管理器——统一管理所有AGC服务的初始化和调用
import { agConnect } from '@hms.core.agconnect';
import { analyticsService } from '@hms.core.analytics';
import { pushService } from '@hms.core.push';
import { remoteConfig } from '@hms.core.remoteconfig';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { common } from '@kit.AbilityKit';
// AGC服务初始化状态
interface AGCInitStatus {
core: boolean; // AGC核心是否初始化
analytics: boolean; // 分析服务是否就绪
push: boolean; // 推送服务是否就绪
remoteConfig: boolean; // 远程配置是否就绪
}
export class AGCManager {
private static instance: AGCManager;
private context: common.Context | null = null;
private initStatus: AGCInitStatus = {
core: false,
analytics: false,
push: false,
remoteConfig: false
};
// 单例模式——全局只有一个AGC管理器
static getInstance(): AGCManager {
if (!AGCManager.instance) {
AGCManager.instance = new AGCManager();
}
return AGCManager.instance;
}
// 初始化所有AGC服务
async initialize(context: common.Context): Promise<void> {
this.context = context;
// 第一步:初始化AGC核心
try {
agConnect.initialize(context);
this.initStatus.core = true;
hilog.info(0x0000, 'AGC', 'AGC核心初始化成功');
} catch (error) {
hilog.error(0x0000, 'AGC', `AGC核心初始化失败: ${JSON.stringify(error)}`);
return; // 核心都没初始化成功,后面别想了
}
// 第二步:并行初始化各服务
const initPromises = [
this.initAnalytics(),
this.initPush(),
this.initRemoteConfig()
];
await Promise.allSettled(initPromises);
hilog.info(0x0000, 'AGC', `AGC服务初始化完成: ${JSON.stringify(this.initStatus)}`);
}
// 初始化分析服务
private async initAnalytics(): Promise<void> {
try {
await analyticsService.initialize();
this.initStatus.analytics = true;
hilog.info(0x0000, 'AGC', '分析服务初始化成功');
} catch (error) {
hilog.error(0x0000, 'AGC', `分析服务初始化失败: ${JSON.stringify(error)}`);
}
}
// 初始化推送服务
private async initPush(): Promise<void> {
try {
const isAvailable = await pushService.isAvailable();
if (isAvailable) {
const token = await pushService.getToken();
this.initStatus.push = true;
hilog.info(0x0000, 'AGC', `推送服务初始化成功, Token: ${token}`);
} else {
hilog.warn(0x0000, 'AGC', '推送服务不可用(可能是设备不支持或未登录华为账号)');
}
} catch (error) {
hilog.error(0x0000, 'AGC', `推送服务初始化失败: ${JSON.stringify(error)}`);
}
}
// 初始化远程配置
private async initRemoteConfig(): Promise<void> {
try {
// 设置默认值——网络不通时使用这些值
const defaults: Record<string, Object> = {
'welcome_message': '欢迎使用本应用',
'feature_flag_new_ui': false,
'max_retry_count': 3,
'maintenance_mode': false
};
remoteConfig.applyDefault(defaults);
// 从服务端拉取最新配置
await remoteConfig.fetch(3600); // 缓存3600秒
await remoteConfig.apply();
this.initStatus.remoteConfig = true;
hilog.info(0x0000, 'AGC', '远程配置初始化成功');
} catch (error) {
hilog.error(0x0000, 'AGC', `远程配置初始化失败: ${JSON.stringify(error)}`);
}
}
// 上报自定义事件
reportEvent(eventName: string, params: Record<string, Object> = {}): void {
if (!this.initStatus.analytics) {
hilog.warn(0x0000, 'AGC', '分析服务未就绪,跳过事件上报');
return;
}
try {
analyticsService.onEvent({
name: eventName,
params: params
});
hilog.info(0x0000, 'AGC', `事件上报成功: ${eventName}`);
} catch (error) {
hilog.error(0x0000, 'AGC', `事件上报失败: ${JSON.stringify(error)}`);
}
}
// 获取远程配置值
getRemoteConfig(key: string, defaultValue: string = ''): string {
if (!this.initStatus.remoteConfig) {
hilog.warn(0x0000, 'AGC', '远程配置未就绪,返回默认值');
return defaultValue;
}
try {
return remoteConfig.getValueAsString(key);
} catch (error) {
hilog.error(0x0000, 'AGC', `获取远程配置失败: ${JSON.stringify(error)}`);
return defaultValue;
}
}
// 获取远程配置布尔值
getRemoteConfigBool(key: string, defaultValue: boolean = false): boolean {
if (!this.initStatus.remoteConfig) {
return defaultValue;
}
try {
return remoteConfig.getValueAsBoolean(key);
} catch (error) {
return defaultValue;
}
}
// 获取初始化状态
getInitStatus(): AGCInitStatus {
return { ...this.initStatus };
}
}
在EntryAbility中使用:
// entry/src/main/ets/entryability/EntryAbility.ets
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { AGCManager } from '../utils/AGCManager';
export default class EntryAbility extends UIAbility {
async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
hilog.info(0x0000, 'EntryAbility', 'onCreate');
// 初始化AGC所有服务
const agcManager = AGCManager.getInstance();
await agcManager.initialize(this.context);
// 检查初始化结果
const status = agcManager.getInitStatus();
hilog.info(0x0000, 'EntryAbility', `AGC初始化状态: ${JSON.stringify(status)}`);
}
onWindowStageCreate(windowStage: window.WindowStage): void {
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
hilog.error(0x0000, 'EntryAbility', `加载失败: ${JSON.stringify(err)}`);
return;
}
});
}
}
在页面中使用远程配置控制功能开关:
// entry/src/main/ets/pages/Index.ets
import { AGCManager } from '../utils/AGCManager';
@Entry
@Component
struct Index {
@State welcomeMsg: string = '加载中...';
@State showNewUI: boolean = false;
@State isMaintenance: boolean = false;
aboutToAppear() {
const agc = AGCManager.getInstance();
// 从远程配置获取欢迎语
this.welcomeMsg = agc.getRemoteConfig('welcome_message', '你好');
// 从远程配置获取功能开关
this.showNewUI = agc.getRemoteConfigBool('feature_flag_new_ui', false);
// 从远程配置获取维护模式
this.isMaintenance = agc.getRemoteConfigBool('maintenance_mode', false);
// 上报页面访问事件
agc.reportEvent('page_view', { page_name: 'index' });
}
build() {
Column({ space: 20 }) {
if (this.isMaintenance) {
// 维护模式
Text('应用维护中,请稍后再试')
.fontSize(20)
.fontColor('#FF0000')
} else {
// 正常模式
Text(this.welcomeMsg)
.fontSize(24)
.fontWeight(FontWeight.Bold)
if (this.showNewUI) {
Text('🎉 新版UI已启用')
.fontSize(16)
.fontColor('#4ECDC4')
}
Button('查看详情')
.width('60%')
.onClick(() => {
AGCManager.getInstance().reportEvent('button_click', {
button_name: 'view_detail',
ui_version: this.showNewUI ? 'new' : 'old'
});
})
}
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
踩坑与注意事项
坑1:agconnect-services.json放错位置
这个文件必须放在entry/src/main/resources/rawfile/目录下。放错位置或者忘了放,SDK初始化直接报错,而且错误信息还不太明确,你可能会以为是网络问题或者包名不对,排查半天。
正确做法:每次从AGC控制台下载配置文件后,第一时间检查文件位置。如果项目有多模块结构,只在entry模块放一份就行。
坑2:SHA256指纹没配或者配错
推送服务、认证服务这些都需要校验应用签名。你在AGC控制台配置的SHA256指纹必须和你打包用的证书指纹一致。
调试时用调试证书的指纹,发布时用发布证书的指纹。两个都要配,不然调试阶段推送就收不到。
获取SHA256指纹的命令:
keytool -list -v -keystore your_keystore.p12 -storetype PKCS12
坑3:AGC服务初始化时机不对
agConnect.initialize()必须在Ability的onCreate中调用,不能延迟到页面加载时才初始化。因为页面可能需要立即使用AGC服务(比如远程配置),如果AGC还没初始化完,服务调用就会失败。
最佳实践:在EntryAbility的onCreate中await初始化完成,再加载页面。
坑4:推送Token获取失败
Push Token获取失败的原因很多:
- 设备没有安装华为移动服务(HMS Core)
- 设备没有登录华为账号
- 网络不通
- 指纹配置错误
排查顺序:先检查isAvailable()返回值,再检查网络,再检查指纹配置。
坑5:远程配置缓存导致值不更新
远程配置有缓存机制,默认缓存12小时。你在AGC控制台改了配置,客户端可能不会立即生效。
开发阶段可以缩短缓存时间:
// 开发模式:缓存60秒
await remoteConfig.fetch(60);
// 生产模式:缓存3600秒(1小时)
await remoteConfig.fetch(3600);
或者直接调用fetch(0)强制拉取最新值(但会消耗更多流量,生产环境慎用)。
HarmonyOS 6适配说明
HarmonyOS 6对AGC的集成方式做了几项重要调整:
-
SDK依赖方式变更:从ohpm统一管理,不再需要手动配置maven仓库地址。直接在
oh-package.json5中添加依赖即可。 -
权限模型升级:推送服务需要动态申请通知权限,不能只在
module.json5中声明就完事。必须在运行时用@kit.AbilityKit的requestPermissionsFromUser()申请。 -
隐私合规增强:所有AGC服务在首次使用前必须获得用户明确同意。建议在应用首次启动时展示隐私协议弹窗,用户同意后再初始化AGC。
-
后台任务限制:推送Token的获取和上报不能放在后台任务中执行,必须在前台Ability中完成。
// HarmonyOS 6 动态申请通知权限示例
import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
async function requestNotificationPermission(context: common.Context): Promise<boolean> {
const permission: Permissions = 'ohos.permission.NOTIFICATION_CONTROLLER';
const atManager = abilityAccessCtrl.createAtManager();
try {
const result = await atManager.requestPermissionsFromUser(context, [permission]);
return result.authResults[0] === 0;
} catch (error) {
hilog.error(0x0000, 'Permission', `申请通知权限失败: ${JSON.stringify(error)}`);
return false;
}
}
总结
AppGallery Connect是HarmonyOS开发者绕不过去的基础设施。从账号注册到服务集成,每一步都有讲究。核心记住三点:
- 先把账号和资质搞定,别等项目快上线了才发现认证没过
- agconnect-services.json是命脉,放对位置、保持同步
- 服务初始化要趁早,在Ability的onCreate中完成,别拖到页面里
| 维度 | 评价 |
|---|---|
| 学习难度 | ⭐⭐⭐ 概念不难,但配置环节多,容易踩坑 |
| 使用频率 | ⭐⭐⭐⭐⭐ 只要上架就必须用,而且会反复用 |
| 重要程度 | ⭐⭐⭐⭐⭐ 不集成AGC,你的应用就是一座孤岛 |
- 点赞
- 收藏
- 关注作者
评论(0)