HMS Cordova推送插件后台透传消息处理逻辑与流程

原创
07/06 19:18
阅读数 1.6K

背景

近期HMS Cordova Push的插件对应用处于后台,或者被关闭状态下透传消息的处理逻辑做了调整。调整后很多开发者反馈不知道应该如何使用,应用切换后台之后就无法收到透传消息了。这里介绍Cordova Push插件后台消息的处理基本流程,供开发者参考。

简介

当应用处于前台运行状态时,如果收到透传消息,将通过发送REMOTE_DATA_MESSAGE_RECEIVED 事件,触发消息处理。而当应用处于后台或关闭状态时,由于JS无法在前台正常执行,导致处理方式产生变化。这里需要注意的是,根据Push的规范要求,原则上当普通应用处于后台时,无法接收透传消息,需要申请特殊权限:https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides-V5/faq-0000001050042183-V5#ZH-CN_TOPIC_0000001134031055__section037425218509?ha_source=hms1

这里只讨论当应用已拥有特殊权限,或者手机终端为海外版本的情况。

后台/关闭状态下透传消息的处理流程

Cordova Push插件对透传消息的处理有两种:新流程和老流程。两者不同点在于,新流程中用户可以操作的空间更大,而老的流程中只能进行本地消息发送。从5.1.1.301版本开始,系统使用新的流程,在此版本之前,系统使用的是老流程。两种流程都包含了两个步骤:脚本定义,脚本加载。

1. 脚本定义

开发者需要在应用启动阶段,定义后台/关闭状态下处理透传消息的方法。与正常运行状态下的不同,这部分处理不是在onRemoteMessageReceived中进行的。在老流程中,开发者需要在setBackgroundAction中进行定义消息处理方式。由于插件中的定义约束,系统仅支持将Data Message中的内容获取后转为本地消息,不支持其他处理类型,如:

HmsPush.setBackgroundAction((remoteMessage) => {
    const jsonData = JSON.parse(remoteMessage.data);
    const headlessNotification = {
        "title": "[Headless] " + jsonData.title,
        "message": jsonData.message.replace("{{name}}","YourName")
    };
    console.log("setBackgroundAction callback ", JSON.stringify(result, "\n", 4));
    const notification = JSON.stringify(headlessNotification);
    HmsLocalNotification.backgroundLocalNotification(notification);
})

在新流程中,setBackgroundAction接口已停止使用,取而代之的是setBackgroundFile接口。开发者需要通过这个接口,设置处理后台/关闭状态下透传消息的具体脚本文件,如:

HmsPush.setBackgroundFile("www/background.js");

用户可以在文件中定义处理逻辑,带来更大的处理灵活度。处理代码如下:

onBackgroundRemoteMessageReceived((remoteMessage)=>{
    const jsonData = JSON.parse(remoteMessage.data);
    const headlessNotification = {
                "title": "[Headless] " + jsonData.title,
                "message": jsonData.message.replace("{{name}}","YourName")
            };
    const notification = JSON.stringify(headlessNotification);
    HmsLocalNotification.backgroundLocalNotification(notification);
});

onBackgroundRemoteMessageReceived为功能入口,将在该函数中完成相关操作。系统将会把setBackgroundAction中设置的函数或setBackgroundFile设置的文件路径保存在SharedPreferences中。

2.  脚本加载

当应用收到透传消息时,HmsPushMessageService类中的onMessageReceived处理将被触发。系统会判断当前状态,如果当前系统处于前台状态,将正常触发消息响应,向前台传递消息内容。如果当前为非前台状态,系统将触发脚本读取:

boolean isApplicationInForeground = ApplicationUtils.isApplicationInForeground(getApplicationContext());
if (isApplicationInForeground) {
   // Foreground process flow
} else {
    // Background process flow
}

在该流程中,由于当前没有前台进程,系统将创建一个webView:

webView = new WebView(getApplicationContext());

在新流程中Webview中将打开Java脚本能力,DOM缓存,文件访问等,并且使能HmsLocalNotification和HmsPush的脚本。在backgroud.js中可以访问这两类接口。在老流程中,Webview的能力有所减弱。最后会读取配置的脚本文件中的内容,并触发onBackgroundRemoteMessageReceived函数

String definedFunction = wrapInsideScriptTag(onBackgroundRemoteMessageReceived() + getItemResponseListener()  + readFile(this,filename) + onRemoteMessageEvent);
webView.loadDataWithBaseURL("file:///android_assets/",definedFunction,"text/html","utf-8",null);

而在老流程中,系统将setBackgroundAction中定义的脚本构造为处理脚本,在WebView中加载。

注意点

1. 不论是新流程还是老流程,在脚本中对消息处理需要和实际发送消息对应,如:

const jsonData = JSON.parse(remoteMessage.data);
const headlessNotification = {
            "title": "[Headless] " + jsonData.title,
            "message": jsonData.message.replace("{{name}}","YourName")
        };

脚本中包含了jsonData.title和jsonData.message,那么在透传消息中也需要包含title和message字段。否则会由于解析失败而导致处理中断。如果透传消息中的字段名变更,处理脚本只要同样修改即可。

2. 在新流程的处理中,由于cordova平台并未启动,因此cordova的函数在脚本中无法使用,只能用到Java Script的基本接口以及HMSPush的接口。

3. 在调试后台处理脚本时,由于非Chrome浏览器无法打印console.log日志,HMS手机中原生浏览器会导致日志无法打印,影响定位。建议使用G+H的手机进行调测。如果

4. 如果消息未成功接收,在日志中搜索“** onMessageReceived **”,如果有相关日志,则消息已经接收到,可以按照以上的流程进行梳理,分析其他日志。如果未搜索到,则消息并未接收到。此时需要排查应用是否申请了“简介”中说明的特殊权限,或者手机是否为海外机型。如果排查确认没有问题,则需要在服务端确认消息发送是否成功。

小结

通过以上的方式,实现了应用处于后台/关闭状态下,透传消息的处理。这里并不涉及普通通知的操作。不论应用处于何种状态,普通通知的处理方式都保持一致,因为系统会自动将应用唤醒。这里建议开发者,如果可以通过普通通知的方式实现,建议采用普通通知,处理逻辑更简单,数据的处理方式也更丰富。

>>访问HMS Core官网,了解更多相关内容
>>获取HMS Core Cordova插件开发指导文档
>>华为HMS Core官方论坛
>>华为HMS Core Cordova插件开源仓库地址:GitHub

点击右上角头像右方的关注,第一时间了解华为移动服务最新技术~

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部