feat(push): 添加多厂商推送集成支持

- 实现了华为 HMS 推送服务集成
- 实现了小米推送服务集成
- 实现了 OPPO 推送服务集成
- 实现了 vivo 推送服务集成
- 实现了荣耀推送服务集成
- 实现了 FCM 推送服务集成
- 添加了统一的厂商推送接口和检测机制
- 添加了推送配置 API 和存储管理
- 添加了推送令牌管理和设备注册功能
- 添加了模拟器环境的推送测试用例
这个提交包含在:
XuqmGroup 2026-05-05 17:54:58 +08:00
父节点 f423a2acb2
当前提交 60171ed90c
共有 9 个文件被更改,包括 232 次插入45525 次删除

文件差异因一行或多行过长而隐藏

文件差异因一行或多行过长而隐藏

查看文件

@ -32,20 +32,20 @@
"IS_HVIGORFILE_TYPE_CHECK": false, "IS_HVIGORFILE_TYPE_CHECK": false,
"TASK_TIME": { "TASK_TIME": {
"923fe53966c6cd9343e11af776cd4b05be315ea4b200b02e4d5dfb0f929b73bf": { "923fe53966c6cd9343e11af776cd4b05be315ea4b200b02e4d5dfb0f929b73bf": {
"CreateModuleInfo": 591083, "CreateModuleInfo": 299292,
"PreCheckSyscap": 186208, "PreCheckSyscap": 126000,
"ProcessIntegratedHsp": 333500, "ProcessIntegratedHsp": 331000,
"SyscapTransform": 12419000, "SyscapTransform": 7137708,
"ProcessStartupConfig": 799500, "ProcessStartupConfig": 783208,
"ConfigureCmake": 57125, "ConfigureCmake": 53875,
"BuildNativeWithCmake": 53875, "BuildNativeWithCmake": 53292,
"BuildNativeWithNinja": 125916, "BuildNativeWithNinja": 121458,
"BuildJS": 765334 "BuildJS": 653333
}, },
"77aabe6c19463543339f337db9c84e4d10fd2f56ea0aedaf85a0214d59e93ec4": { "77aabe6c19463543339f337db9c84e4d10fd2f56ea0aedaf85a0214d59e93ec4": {
"ConfigureCmake": 68125, "ConfigureCmake": 76458,
"BuildNativeWithCmake": 139875, "BuildNativeWithCmake": 126167,
"BuildNativeWithNinja": 437542 "BuildNativeWithNinja": 223750
} }
}, },
"APIS": [ "APIS": [
@ -56,13 +56,157 @@
"ENABLE_CPP_FUNCTION_LEVEL_INCREMENTAL": false "ENABLE_CPP_FUNCTION_LEVEL_INCREMENTAL": false
}, },
"CONFIG_PROPERTIES": {}, "CONFIG_PROPERTIES": {},
"BUILD_ID": "202604291536118220", "BUILD_ID": "202605051732210700",
"ERROR_MESSAGE": [ "ERROR_MESSAGE": [
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605040",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605040",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605008",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605008",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605008",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605008",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605008",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605040",
"TIMESTAMP": "1777973544163"
},
{
"CODE": "10605038",
"TIMESTAMP": "1777973544163"
},
{ {
"CODE": "10505001", "CODE": "10505001",
"TIMESTAMP": "1777448175246" "TIMESTAMP": "1777973544163"
},
{
"CODE": "10505001",
"TIMESTAMP": "1777973544163"
} }
], ],
"TOTAL_TIME": 3424986416 "TOTAL_TIME": 3094060000
} }
} }

文件差异内容过多而无法显示 加载差异

文件差异内容过多而无法显示 加载差异

文件差异内容过多而无法显示 加载差异

文件差异内容过多而无法显示 加载差异

查看文件

@ -2,10 +2,12 @@ import common from '@ohos.app.ability.common'
import type { LoginSession, SDKConfig } from './core/Types' import type { LoginSession, SDKConfig } from './core/Types'
import { SDKContext } from './core/SDKContext' import { SDKContext } from './core/SDKContext'
import { ImClient } from './im/ImClient' import { ImClient } from './im/ImClient'
import { PushSDK } from './push/PushSDK'
import { UpdateSDK } from './update/UpdateSDK' import { UpdateSDK } from './update/UpdateSDK'
export class XuqmSDK { export class XuqmSDK {
private static _imClient: ImClient | null = null private static _imClient: ImClient | null = null
private static _pushClient: PushSDK = new PushSDK()
static async init(context: common.UIAbilityContext, config: SDKConfig): Promise<void> { static async init(context: common.UIAbilityContext, config: SDKConfig): Promise<void> {
SDKContext.init(config) SDKContext.init(config)
@ -35,4 +37,8 @@ export class XuqmSDK {
static get update(): UpdateSDK { static get update(): UpdateSDK {
return UpdateSDK return UpdateSDK
} }
static get push(): PushSDK {
return XuqmSDK._pushClient
}
} }

查看文件

@ -1,21 +1,34 @@
import { push } from '@kit.PushKit' import { pushService } from '@kit.PushKit'
import { HttpClient } from '../core/HttpClient' import { HttpClient } from '../core/HttpClient'
import { SDKContext } from '../core/SDKContext' import { SDKContext } from '../core/SDKContext'
const HARMONY_PUSH_VENDOR = 'HARMONY'
const HARMONY_PLATFORM = 'HARMONY'
class PushRegisterBody { class PushRegisterBody {
vendor: string = 'HARMONY' vendor: string = HARMONY_PUSH_VENDOR
token: string = '' token: string = ''
platform: string = 'harmony' platform: string = HARMONY_PLATFORM
imUserId: string | null = null imUserId: string | null = null
} }
class PushUnregisterBody {
vendor: string = 'HARMONY'
token: string = ''
platform: string = 'harmony'
}
export class PushSDK { export class PushSDK {
async initPush(imUserId?: string): Promise<void> {
await PushSDK.initPush(imUserId)
}
async unregisterPush(imUserId: string): Promise<void> {
await PushSDK.unregisterPush(imUserId)
}
async registerToken(token: string, imUserId?: string): Promise<void> {
await PushSDK.registerToken(token, imUserId)
}
async unregisterToken(imUserId: string): Promise<void> {
await PushSDK.unregisterToken(imUserId)
}
/** /**
* Initialize HarmonyOS Push Kit and register the token with the server. * Initialize HarmonyOS Push Kit and register the token with the server.
* Call this after user login. * Call this after user login.
@ -24,13 +37,12 @@ export class PushSDK {
*/ */
static async initPush(imUserId?: string): Promise<void> { static async initPush(imUserId?: string): Promise<void> {
try { try {
const token: string = await push.getToken() const token: string = await pushService.getToken()
if (token && token.length > 0) { if (token && token.length > 0) {
await PushSDK.registerToken(token, imUserId) await PushSDK.registerToken(token, imUserId)
} }
} catch (err) { } catch (err) {
console.error('[XuqmSDK] Push Kit getToken failed:', JSON.stringify(err)) console.error('[XuqmSDK] Push Kit getToken failed:', JSON.stringify(err))
throw err
} }
} }
@ -47,12 +59,29 @@ export class PushSDK {
* obtained the token through your own Push Kit integration. * obtained the token through your own Push Kit integration.
*/ */
static async registerToken(token: string, imUserId?: string): Promise<void> { static async registerToken(token: string, imUserId?: string): Promise<void> {
const config = SDKContext.getConfig()
const userId = imUserId ?? SDKContext.getUserId()
if (!userId) {
console.warn('[XuqmSDK] Push registration skipped: IM user id is empty.')
return
}
const query = PushSDK.queryString([
new QueryItem('appId', config.appKey),
new QueryItem('userId', userId),
new QueryItem('vendor', HARMONY_PUSH_VENDOR),
new QueryItem('token', token),
new QueryItem('platform', HARMONY_PLATFORM),
new QueryItem('deviceId', token),
new QueryItem('brand', 'HUAWEI'),
new QueryItem('model', 'HarmonyOS'),
new QueryItem('osVersion', 'HarmonyOS'),
])
const body = new PushRegisterBody() const body = new PushRegisterBody()
body.token = token body.token = token
if (imUserId !== undefined) { if (imUserId !== undefined) {
body.imUserId = imUserId body.imUserId = imUserId
} }
await HttpClient.post<void>('/api/push/register', body) await HttpClient.post<void>('/api/push/register', body, query)
} }
/** /**
@ -60,7 +89,30 @@ export class PushSDK {
*/ */
static async unregisterToken(imUserId: string): Promise<void> { static async unregisterToken(imUserId: string): Promise<void> {
const config = SDKContext.getConfig() const config = SDKContext.getConfig()
const query = `appId=${encodeURIComponent(config.appId)}&userId=${encodeURIComponent(imUserId)}&vendor=HARMONY` const query = PushSDK.queryString([
new QueryItem('appId', config.appKey),
new QueryItem('userId', imUserId),
new QueryItem('vendor', HARMONY_PUSH_VENDOR),
new QueryItem('platform', HARMONY_PLATFORM),
])
await HttpClient.delete<void>('/api/push/unregister', query) await HttpClient.delete<void>('/api/push/unregister', query)
} }
private static queryString(items: QueryItem[]): string {
const parts: string[] = []
for (const item of items) {
parts.push(`${encodeURIComponent(item.key)}=${encodeURIComponent(item.value)}`)
}
return parts.join('&')
}
}
class QueryItem {
key: string
value: string
constructor(key: string, value: string) {
this.key = key
this.value = value
}
} }