【FAQ】HarmonyOS SDK 闭源开放能力 — Push Kit
1.问题描述:
Push token什么场景下会发生变化?
解决方案:
下列场景Push Token会发生变化:
-
卸载应用后重新安装。
-
设备恢复出厂设置。
-
应用显式调用deleteToken()接口后重新调用getToken()接口。
-
应用显式调用deleteAAID()接口后重新调用getToken()接口。
-
将设备(仅涉及Wearable设备)拿到海外其他国家或者地区后,系统会更新设备的Token。更新后的Token通过pushService.on('tokenUpdate')接口的回调返回。
因此,建议在应用启动时调用getToken()接口,若设备的PushToken发生变化,及时上报到应用服务器更新PushToken。
以下是参考示例代码:
// 导入pushService模块及相关公共模块
import { pushService } from '@kit.PushKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
// 建议在UIAbility(例如EntryAbility)的onCreate()方法中调用getToken()接口获取PushToken并上报到服务端,方便服务端向终端推送消息。
try {
pushService.getToken().then((data: string) => {
hilog.info(0x0000, 'testTag', 'Succeeded in getting push token.');
}).catch((err: BusinessError) => {
hilog.error(0x0000, 'testTag', 'Failed to get push token: %{public}d %{public}s', err.code, err.message);
});
} catch (err) {
let e: BusinessError = err as BusinessError;
hilog.error(0x0000, 'testTag', 'Failed to get push token: %{public}d %{public}s', e.code, e.message);
}
2.问题描述:
推送卡片消息需要后台根据卡片页面绑定的字段处理好数据后调用推送服务,如果后台只能传递需要的参数参数,需要卡片里根据参数使用网络请求获取更多数据后刷新到卡片页面上,如何实现?
解决方案:
【背景知识】
-
推送卡片刷新消息:面对需要实时更新信息的应用卡片,Push Kit向开发者提供了卡片刷新服务。应用通过集成Push Kit后获取Push Token,基于Push Kit的系统级通道,便可以在合适场景向用户即时推送卡片内容,从而提升用户的感知度和活跃度。
-
message事件:可以使用message拉起FormExtensionAbility,通过onFormEvent接口回调通知,以完成点击卡片控件后传递消息给应用的功能。
-
postCardAction:在卡片页面中可以通过postCardAction接口触发事件拉起UIAbility,然后由UIAbility刷新卡片内容。
【解决方案】
- 按照开发步骤进行卡片和推送消息的开发。不同之处在于推送消息体中传递的字段换成需要的参数:
{
"payload": {
"moduleName": "entry",
"abilityName": "EntryFormAbility",
"formName": "widget",
"formId": 42***62,
"version": 12**56,
"formData": {
"query_key": "123****45"
}
},
"target": {
"token": [
"MAMzLg**********lPW"
]
},
"pushOptions": {
"testMessage": true
}
}
- 在卡片页面使用@LocalStorageProp修饰formData中传递的参数,并使用@watch监听。
@Watch('refresh') @LocalStorageProp('query_key') queryKey: number = -1;
- 当参数变化时使用postCardAction向发送message事件拉起UIAbility,传递参数。
refresh() {
postCardAction(this, {
action: 'message',
params: {
queryKey: this.queryKey
}
});
}
- 在FormExtensionAbility的onFormEvent生命周期中使用网络请求获取到需要的信息,组装数据后调用updateForm接口刷新卡片内容。
注意事项:此方式需要保证onFormEvent在10秒内能处理完业务,请参考卡片生命周期管理。若无法保证onFormEvent在10秒内能处理完业务,请在后台处理完数据后再推送消息,请参考推送卡片刷新消息。
3.问题描述:
App按照文档设置了自定义铃声:申请自定义铃声权益和通知消息自定义铃声实现,铃声持续时间半分钟以上。当收到通知,铃声开始响,但是点击收到的通知打开App后,铃声依旧在播放。
解决方案:
可以在打开应用时,对当前应用的消息通知做清除操作,示例代码如下:
import { BusinessError } from '@kit.BasicServicesKit';
export default class EntryAbility extends UIAbility {
onForeground(): void {
// Ability has brought to foreground
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
let cancelAllCallback = (err: BusinessError): void => {
if (err) {
console.error(`Failed to cancel all notification. Code is ${err.code}, message is ${err.message}`);
} else {
console.info(`Succeeded in canceling all notification.`);
}
}
notificationManager.cancelAll(cancelAllCallback);
}
}
4.问题描述:
生命周期onCreate()或者onNewWant()里want中的uri是HarmonyOS自动生成的吗?
解决方案:
生命周期onCreate()或者onNewWant()里want中的uri为统一资源标识符,一般在应用启动场景中配合type使用,指明待处理的数据类型。如果在拉起方的Want中指定了uri,则Want将匹配指定的Uri信息,包括scheme、schemeSpecificPart、authority和path信息, 生命周期onCreate()或者onNewWant()里want中的uri为起方的Want中传递的uri,不传则默认为空字符串。例外:通过push kit拉起的场景下拉起方不是使用的want的方式,系统自动给uri赋值为"abilityEvent:clickAlertMessage"。
5.问题描述:
要实现App进入后台或App杀死后收到推送消息,是否要必须接入推送通知扩展消息并申请推送通知扩展消息权益?
解决方案:
设备处于离线状态,即关机或者无网络状态,和App是否处于进程中没有关联。
如果设备有网络连接,无论App是否处于进程中,都可以收到推送消息。
如果设备已经处于离线状态,开发者可以通过请求体中ttl参数控制消息在Push服务器缓存的时间,在消息缓存时间内用户设备上线,消息会下发,超过缓存时间后消息会丢弃。
6.问题描述:
用户反馈收到通知都是时好时坏,有大概率根本收不到push。
解决方案:
【背景知识】
-
Push Kit(推送服务):华为提供的消息推送平台,建立了从云端到终端的消息推送通道。
-
申请推送场景化消息权益:Push Kit支持多种场景化消息类型,其中部分场景化消息类型需要开发者申请特殊权益才能正常发送。
-
请求通知授权:应用需要获取用户授权才能发送通知。
-
开发消息回执:消息回执是指Push Kit服务端将消息推送到用户终端之后,端侧会给Push服务端反馈送达结果。与此同时,Push服务端会将消息送达状态以回执消息形式发送给应用回执服务端,方便开发者获取消息下达端侧后的状态,定位问题等。
-
发送消息通知:通知消息通过Push Kit通道直接下发,可在终端设备的通知中心、锁屏、横幅等展示,用户点击后拉起应用。
【问题定位】
用户收到了消息:
-
检查是否是静默通知。
-
检查是否手动关闭了消息提醒方式。
用户未收到消息:
-
检查Push token是否正确。
-
检查Authorization请求体是否错误。
-
检查是否推送后台消息场景。
-
检查设备是否离线。
-
检查自分类权益是否已申请,是否开启状态。
-
检查是否受到消息频控。
-
检查配置文件是否配置错误。
【分析结论】
-
资讯营销类消息的通知方式是静默通知,仅在通知中心展示消息。
-
服务与通讯类消息的通知方式默认是锁屏、铃声、振动,用户手动关闭锁屏、铃声、振动,导致未收到提示。
-
消息推送参数配置错误、被频控等情况下会导致消息推送失败。
【修改建议】
-
当收到资讯营销类消息时,由于静默通知仅在通知中心展示,并不会弹框提示,需要去通知中心查看。通知中心如下图,可以查看对应消息。
![]()
-
若终端上的app手动关闭了消息提醒方式,终端收到消息不会有提醒,需要打开所需的提醒方式。
![]()
-
打开AGC平台,选择我的项目,然后选择推送服务,在自主分析里面,输入requestId和token,系统会自动分析消息推送失败的可能原因。
也可能是Push token不是最新的token,建议通过getToken()方法获得Push token后,第一时间推送到服务端。
-
检查服务端发送请求时是否正确携带Authorization请求头,value为JWT格式字符串,是基于服务账号生成鉴权令牌。可参考:请求体结构说明。
-
推送后台消息用于内容不频繁更新的场景,不会显示通知、播放铃声或改变应用角标。终端设备接收到后台消息后,如果应用进程在前台则将消息内容传给应用;如果应用进程不在前台则缓存消息,等待应用启动后再传给应用。
-
如果设备离线,Push Kit会缓存消息,待设备上线后,再将消息推送给设备。
-
检查自分类权益是否已申请,并且打开自分类权益开关,请参考:申请推送场景化消息权益。
-
检查是否受到消息频控。
*调测阶段:每个项目每个自然日最多可推送1000条测试消息(非设备级,所有设备共用1000条),且不受场景化消息频控限制(即不区分通知消息类别、不区分场景化消息类别)。可以在消息发送请求体中设置pushOptions.testMessage为true,发送测试消息。
- 正式发布阶段:单设备单应用下每个自然日最多可推送3000条消息,并受场景化消息频控限制。
-
检查module.json5中skills配置是否正确。
-
应用只需要配置一条skill对象。
设置action参数点击消息进入应用页面(若skills中添加了uris参数,则uris内容需为空)
{ "actions": [ "com.test.action" ] }设置uris参数点击消息进入应用页面(skills中必须同时设置actions参数,actions参数需为空)
{ "actions": [ "" ], "uris": [ { "scheme": "https", "host": "www.xxx.com", "port": "8080", "path": "push/test" } ] }-
应用需要配置多条skill对象。
比如同时设置推送消息跳转能力和其他跳转能力(如NFC跳转、浏览器跳转等),可以在skills数组中创建不同的skill对象,分别映射对应的能力。
-
{
"name": "TestAbility",
"srcEntry": "./ets/abilities/TestAbility.ets",
"exported": false,
"startWindowIcon": "$media:icon",
"startWindowBackground": "$color:start_window_background",
"skills": [
// 保持现有skill对象不变
{
"actions": [
"com.app.action"
]
},
// 新增一个独立的skill对象,配置uris参数,且必须同时配置actions参数,actions参数为空字符串
{
"actions": [""],
"uris": [
{
"scheme": "https",
"host": "www.xxx.com",
"port": "8080",
"path": "push/test"
}
]
},
{
// 分享
"actions": [
"ohos.want.action.sendData"
],
"uris": [
{
"scheme": "file",
"type": "text/plain"
}
]
}
]
}
【总结】
Push Kit消息下发成功后,可能会因为消息频控、通知开关未打开等原因,导致端侧消息未展示。通常可以从消息通知是否打开、消息分类权益是否申请、配置文件中skills标签是否正确这几个方面进行排查。同时,建议开发消息回执,Push服务端会将消息送达状态以回执消息形式发送给应用回执服务端,方便获取消息下达端的状态,通过回执状态码定位问题。


浙公网安备 33010602011771号