鸿蒙5应用消息推送:AGC Push通知集成详解
一、AGC Push服务介绍与准备工作
- AGC Push服务概述
AGC Push是华为提供的消息推送服务,支持多种消息类型:
通知栏消息
透传消息
富媒体消息
定时消息
2. 开通Push服务
登录AppGallery Connect
进入你的项目
选择"增长" > "推送服务"
点击"立即开通"按钮
3. 配置HarmonyOS项目
在entry/build.gradle中添加依赖:
dependencies {
// AGC核心库
implementation 'com.huawei.agconnect:agconnect-core-harmony:1.6.5.300'
// Push服务库
implementation 'com.huawei.agconnect:agconnect-push-harmony:1.6.5.300'
}
二、Push服务初始化与配置
- 初始化AGC Push服务
在EntryAbility.ets中进行初始化:
import agconnect from '@hw-agconnect/core';
import push from '@hw-agconnect/push';
@Entry
@Component
struct EntryAbility {
onWindowStageCreate(windowStage: Window.WindowStage) {
// 初始化AGC
agconnect.instance().init();
// 初始化Push服务
push.instance().init();
// 设置默认通知处理
push.instance().on('pushMessageReceived', (data) => {
console.log('收到推送消息:', JSON.stringify(data));
// 这里可以添加自定义处理逻辑
});
}
}
2. 获取Push Token
创建PushManager.ets工具类:
import push from '@hw-agconnect/push';
export class PushManager {
private static instance: PushManager | null = null;
private constructor() {}
public static getInstance(): PushManager {
if (!PushManager.instance) {
PushManager.instance = new PushManager();
}
return PushManager.instance;
}
// 获取设备Push Token
async getPushToken(): Promise<string> {
try {
const token = await push.instance().getToken();
console.log('Push Token:', token);
return token;
} catch (error) {
console.error('获取Push Token失败:', error);
throw error;
}
}
// 删除Push Token
async deleteToken(): Promise<void> {
try {
await push.instance().deleteToken();
console.log('Push Token已删除');
} catch (error) {
console.error('删除Push Token失败:', error);
throw error;
}
}
}
三、实现消息接收与处理
- 配置消息接收监听
在EntryAbility.ets中扩展消息处理:
onWindowStageCreate(windowStage: Window.WindowStage) {
// ...其他初始化代码...
// 监听通知点击事件
push.instance().on('notificationClicked', (data) => {
console.log('通知被点击:', JSON.stringify(data));
this.handleNotificationClick(data);
});
// 监听透传消息
push.instance().on('dataMessageReceived', (data) => {
console.log('收到透传消息:', JSON.stringify(data));
this.handleDataMessage(data);
});
}
private handleNotificationClick(data: any) {
// 解析通知中的自定义参数
const extras = data.notification?.extras || {};
// 根据参数跳转到不同页面
if (extras.page) {
router.pushUrl({
url: extras.page,
params: extras
});
}
}
private handleDataMessage(data: any) {
// 处理透传消息,可以更新UI或执行后台任务
// 注意:透传消息不会自动显示通知
// 需要手动调用通知API显示
this.showLocalNotification(data);
}
private showLocalNotification(data: any) {
try {
const notificationRequest: NotificationManager.NotificationRequest = {
content: {
contentType: NotificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: data.title || '新消息',
text: data.text || '您收到一条新消息',
additionalText: data.additionalText || ''
}
},
id: Date.now(),
isOngoing: false,
tapDismissed: true,
extras: data.extras || {}
};
NotificationManager.publish(notificationRequest);
} catch (error) {
console.error('显示本地通知失败:', error);
}
}
四、实现消息发送功能
- 服务端发送消息示例(Node.js)
const agconnect = require('@hw-agconnect/server');
// 初始化AGC
agconnect.instance().init({
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
projectId: 'YOUR_PROJECT_ID'
});
// 发送通知消息
async function sendNotificationMessage(tokens, title, body, extras = {}) {
try {
const pushMessaging = agconnect.push().messaging();
const message = {
notification: {
title: title,
body: body
},
android: {
notification: {
click_action: {
type: 1 // 打开应用
},
extras: extras
}
},
tokens: tokens // 设备token数组
};
const response = await pushMessaging.send(message);
console.log('消息发送成功:', response);
return response;
} catch (error) {
console.error('消息发送失败:', error);
throw error;
}
}
// 发送透传消息
async function sendDataMessage(tokens, data) {
try {
const pushMessaging = agconnect.push().messaging();
const message = {
data: data,
tokens: tokens
};
const response = await pushMessaging.send(message);
console.log('透传消息发送成功:', response);
return response;
} catch (error) {
console.error('透传消息发送失败:', error);
throw error;
}
}
2. 鸿蒙端实现消息发送UI
@Entry
@Component
struct PushTestPage {
@State token: string = '';
@State messageTitle: string = '';
@State messageBody: string = '';
@State result: string = '';
private pushManager = PushManager.getInstance();
build() {
Column({ space: 20 }) {
Text('Push通知测试')
.fontSize(24)
.fontWeight(FontWeight.Bold)
Button('获取Push Token')
.width(200)
.height(50)
.onClick(async () => {
try {
this.token = await this.pushManager.getPushToken();
this.result = `Token: ${this.token}`;
} catch (error) {
this.result = `获取Token失败: ${error.message}`;
}
})
TextInput({ text: this.messageTitle })
.placeholder('输入消息标题')
.width('90%')
.onChange((value: string) => {
this.messageTitle = value;
})
TextInput({ text: this.messageBody })
.placeholder('输入消息内容')
.width('90%')
.onChange((value: string) => {
this.messageBody = value;
})
Button('发送测试通知')
.width(200)
.height(50)
.backgroundColor(Color.Green)
.onClick(async () => {
if (!this.token) {
this.result = '请先获取Token';
return;
}
try {
// 这里应该调用后端API发送消息
// 以下是模拟发送的代码
push.instance().on('pushMessageReceived', {
notification: {
title: this.messageTitle,
body: this.messageBody,
extras: {
test: 'true',
time: new Date().toISOString()
}
}
});
this.result = '测试通知已触发';
} catch (error) {
this.result = `发送失败: ${error.message}`;
}
})
Text(this.result)
.fontSize(16)
.width('90%')
.multilineTextAlign(TextAlign.Start)
Text(this.token ? `当前Token: ${this.token}` : '未获取Token')
.fontSize(14)
.width('90%')
.textOverflow({ overflow: TextOverflow.Ellipsis })
}
.width('100%')
.height('100%')
.padding(20)
}
}
五、高级推送功能实现
- 主题订阅与取消
// 在PushManager.ets中添加方法
async subscribeToTopic(topic: string): Promise{
try {
await push.instance().subscribe(topic);
console.log(已订阅主题: ${topic});
} catch (error) {
console.error(订阅主题${topic}失败:, error);
throw error;
}
}
async unsubscribeFromTopic(topic: string): Promise
try {
await push.instance().unsubscribe(topic);
console.log(已取消订阅主题: ${topic});
} catch (error) {
console.error(取消订阅主题${topic}失败:, error);
throw error;
}
}
2. 本地通知管理
// 在PushManager.ets中添加本地通知方法
async scheduleLocalNotification(
id: number,
title: string,
body: string,
delaySeconds: number,
extras?: Object
): Promise
try {
const trigger: NotificationManager.NotificationTrigger = {
type: NotificationManager.TriggerType.TIMER,
timer: {
value: delaySeconds * 1000 // 毫秒
}
};
const notificationRequest: NotificationManager.NotificationRequest = {
content: {
contentType: NotificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: title,
text: body,
additionalText: ''
}
},
id: id,
isOngoing: false,
tapDismissed: true,
extras: extras || {},
trigger: trigger
};
await NotificationManager.publish(notificationRequest);
console.log(`本地通知已计划,ID: ${id}`);
} catch (error) {
console.error('计划本地通知失败:', error);
throw error;
}
}
async cancelLocalNotification(id: number): Promise
try {
await NotificationManager.cancel(id);
console.log(已取消通知,ID: ${id});
} catch (error) {
console.error('取消通知失败:', error);
throw error;
}
}
六、消息统计分析
- 配置消息点击跟踪
在EntryAbility.ets中:
private handleNotificationClick(data: any) {
// 记录消息点击事件
push.instance().reportNotificationClicked(data.msgId);
// ...原有的点击处理逻辑...
}
2. 在AGC控制台查看分析数据
进入"推送服务" > "统计分析"
可以查看:
消息送达率
点击率
用户设备分布
时间趋势分析
七、常见问题与解决方案
- 收不到推送消息
排查步骤:
确认设备已联网
检查Token是否成功获取
验证AGC控制台消息发送状态
检查应用通知权限是否开启
代码检查:
// 检查通知权限
async checkNotificationPermission(): Promise
try {
const result = await NotificationManager.isNotificationEnabled();
console.log('通知权限状态:', result);
return result;
} catch (error) {
console.error('检查通知权限失败:', error);
return false;
}
}
// 打开通知设置页面
async openNotificationSettings() {
try {
await NotificationManager.requestEnableNotification();
} catch (error) {
console.error('打开通知设置失败:', error);
}
}
2. Token失效问题
处理方案:
// 在PushManager.ets中添加Token监听
setupTokenListeners() {
// 监听Token变化
push.instance().on('tokenUpdated', (newToken) => {
console.log('Token已更新:', newToken);
// 这里应该将新Token发送到你的服务器
});
// 监听Token失效
push.instance().on('tokenInvalid', () => {
console.log('Token已失效');
// 重新获取Token
this.getPushToken();
});
}
3. 后台接收限制
解决方案:
添加后台任务权限
实现后台服务处理消息
在module.json5中添加权限:
{
"module": {
"abilities": [
{
"backgroundModes": [
"notification",
"dataTransfer"
]
}
],
"requestPermissions": [
{
"name": "ohos.permission.KEEP_BACKGROUND_RUNNING"
}
]
}
}
八、完整示例:新闻应用推送实现
- 新闻推送服务类
// NewsPushService.ets
import { PushManager } from './PushManager';
export class NewsPushService {
private static instance: NewsPushService | null = null;
private pushManager = PushManager.getInstance();
private constructor() {
this.setupNewsPushListeners();
}
public static getInstance(): NewsPushService {
if (!NewsPushService.instance) {
NewsPushService.instance = new NewsPushService();
}
return NewsPushService.instance;
}
private setupNewsPushListeners() {
// 监听新闻推送
push.instance().on('pushMessageReceived', (data) => {
if (data.notification?.extras?.type === 'news') {
this.handleNewsPush(data);
}
});
}
private handleNewsPush(data: any) {
const extras = data.notification?.extras || {};
const newsId = extras.newsId;
const category = extras.category || 'general';
// 存储未读新闻
this.saveUnreadNews(newsId, category);
// 显示本地通知
this.showNewsNotification(
data.notification.title,
data.notification.body,
extras
);
}
private async saveUnreadNews(newsId: string, category: string) {
// 这里可以实现将未读新闻保存到本地数据库
console.log(`保存未读新闻: ${newsId}, 分类: ${category}`);
}
private showNewsNotification(title: string, body: string, extras: any) {
try {
const notificationRequest = {
content: {
contentType: NotificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: title,
text: body,
additionalText: '点击查看详情'
}
},
id: parseInt(extras.newsId),
isOngoing: false,
tapDismissed: true,
extras: extras
};
NotificationManager.publish(notificationRequest);
} catch (error) {
console.error('显示新闻通知失败:', error);
}
}
// 订阅新闻分类
async subscribeToNewsCategory(category: string) {
try {
await this.pushManager.subscribeToTopic(`news_${category}`);
console.log(`已订阅新闻分类: ${category}`);
} catch (error) {
console.error(`订阅新闻分类${category}失败:`, error);
throw error;
}
}
// 取消订阅新闻分类
async unsubscribeFromNewsCategory(category: string) {
try {
await this.pushManager.unsubscribeFromTopic(`news_${category}`);
console.log(`已取消订阅新闻分类: ${category}`);
} catch (error) {
console.error(`取消订阅新闻分类${category}失败:`, error);
throw error;
}
}
}
2. 新闻页面集成推送
@Entry
@Component
struct NewsDetailPage {
@State newsItem: NewsItem = { id: '0', title: '', content: '' };
@State isSubscribed: boolean = false;
private newsPushService = NewsPushService.getInstance();
build() {
Column() {
Text(this.newsItem.title)
.fontSize(24)
.fontWeight(FontWeight.Bold)
Text(this.newsItem.content)
.fontSize(16)
.margin({ top: 20 })
Button(this.isSubscribed ? '取消订阅此类新闻' : '订阅此类新闻')
.width(200)
.height(50)
.margin({ top: 30 })
.onClick(async () => {
if (this.isSubscribed) {
await this.newsPushService.unsubscribeFromNewsCategory(this.newsItem.category);
} else {
await this.newsPushService.subscribeToNewsCategory(this.newsItem.category);
}
this.isSubscribed = !this.isSubscribed;
})
}
.padding(20)
.width('100%')
.height('100%')
}
onPageShow() {
// 从路由参数获取新闻项
const params = router.getParams();
if (params && params.newsItem) {
this.newsItem = params.newsItem;
// 检查是否已订阅
this.checkSubscriptionStatus();
}
}
async checkSubscriptionStatus() {
// 这里应该实现检查用户是否已订阅此类新闻
// 简化示例,假设使用本地存储
this.isSubscribed = localStorage.get(`subscribed_${this.newsItem.category}`) === 'true';
}
}
总结
通过本文的详细讲解,你已经掌握了在HarmonyOS 5应用中集成AGC Push服务的完整流程:
环境配置:正确初始化Push服务和配置项目
Token管理:获取和管理设备Push Token
消息处理:实现通知和透传消息的接收与处理
高级功能:主题订阅、本地通知和统计分析
实战案例:新闻应用的完整推送实现
实际开发中,你还可以进一步探索:
推送消息的A/B测试
基于用户行为的精准推送
推送消息的个性化定制
与其他AGC服务(如Analytics)的集成

浙公网安备 33010602011771号