最近在做Cordova
的消息推送,在集成厂商通道的时候发现不能在js
中使用jpush.openNotification
或者jpush.receiveNotification
事件来监听收到消息提示。
因为厂商通道并没有走JPushEventReceiver.onNotifyMessageOpened
方法,因此没有事件发出来。
目前cordova
版本的jpush sdk
是4.2.8
版本,据官方说4.6.x
的厂商通道就支持
地址:https://github.com/jpush/jpush-phonegap-plugin
前提:已经配置好厂商通道
本文是介绍原理,如果直接使用,可以直接跳到【GitHub
地址】章节,也可以直接访问GitHub
地址:
GitHub
地址:https://github.com/fugary/cordova-plugin-jpush-custom
监听方式
现有启动逻辑
window.JPush.init()
window.JPush.setDebugMode(true)
window.setTimeout(getRegistrationID, 1000) // 获取RegistrationID
document.addEventListener('jpush.openNotification', evt => {
// 事件处理
}, false)
document.addEventListener('jpush.receiveNotification', evt => {
// 事件处理
}, false)
配置好厂商通道之后,本地以vivo
手机测试,可以推送消息,但是点消息没有反应,打不开APP
。
发送端修改
目前使用Java
调用服务端SDK
发送消息, 需要添加uri_activity
属性setUriActivity("com.xxx.MainActivity")
就可以实现点击消息可以打开APP
了。
JPushClient jPushClient = new JPushClient("MasterSecret", "AppKey");
String messageTitle = "Test消息标题";
String messageContent = "Test消息内容消息内容";
String registrationId = "1507bfd3f7366d1c33b";
String platform = "android";
boolean isAndroid = platform.equalsIgnoreCase("android");
// 添加一些extras信息
Map extras = new HashMap<>();
extras.put("orderNo", "xxxxxx");
// iOS消息
IosAlert alert = IosAlert.newBuilder().setTitleAndBody(messageTitle, "", messageContent).build();
Notification androidNotification = Notification.newBuilder()
.addPlatformNotification(AndroidNotification.newBuilder()
.setAlert(messageContent).setTitle(messageTitle).addExtras(extras)
.setUriActivity("com.xxx.MainActivity") // cordova的activity全称,packageName.MainActivity
.build()).build();
PushPayload pushPayload = PushPayload.newBuilder()
.setAudience(Audience.registrationId(registrationId))
.setPlatform(isAndroid ? Platform.android() : Platform.ios())
.setNotification(isAndroid ? androidNotification : Notification.ios(alert, extras))
.setOptions(getVivoOptions())
.build();
PushResult pushResult = jPushClient.sendPush(pushPayload);
然后再次尝试,收到消息后可以在vivo
手机上打开消息了。
不过还是没有触发事件,没法定制收到消息打开APP
之后的逻辑。
开发Cordova插件
参考:https://fugary.com/?p=339
因为消息发送到`Activity`之后,可以用`Intent`获取到,不过刚打开`APP`获取到消息的时候`Cordova`环境并没有初始化好,`WebView`也没有加载完,这时候不能直接发出事件。因此目前思路是开发一个`Cordova`插件,在初始化的时候把`Intent`中的数据取出来存在Java的属性中,然后再初始化完成后调用一个`JS`方法来获取数据,在`JS`中触发极光推送的事件`jpush.receiveNotification`事件,这样原来监听的事件就可以使用了。
插件Java代码
参考Intent
数据获取:https://docs.jiguang.cn/jpush/practice/intent
插件主要Java
代码,数据先存储在extraMessage
中,然后通过checkReceiveMessage
方法取数据:
public class JPushCustomPlugin extends CordovaPlugin {
private static final String TAG = JPushCustomPlugin.class.getSimpleName();
private Activity cordovaActivity;
private JPushCustomPlugin instance;
private String extraMessage;
@Override
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
super.initialize(cordova, webView);
cordovaActivity = cordova.getActivity();
instance = this;
LOG.i(TAG, "init JPushCustomPlugin ...................................");
processJPushMessage(cordovaActivity);
}
protected void processJPushMessage(Activity cordovaActivity) {
if (instance == null) {
return;
}
extraMessage = getNotificationExtras(cordovaActivity.getIntent());
LOG.i(TAG, "JPush Message: %s", extraMessage);
}
protected String getNotificationExtras(Intent intent) {
String data = null;
if (intent != null) {
//获取华为平台附带的jpush信息
if (intent.getData() != null) {
data = intent.getData().toString();
}
//获取fcm/oppo/小米/vivo/魅族 平台附带的jpush信息
if (TextUtils.isEmpty(data) && intent.getExtras() != null) {
data = intent.getExtras().getString("JMessageExtra");
}
}
return data;
}
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
if (action.equals("coolMethod")) {
String message = args.getString(0);
this.coolMethod(message, callbackContext);
return true;
}
if (action.equals("checkReceiveMessage")) {
this.checkReceiveMessage(callbackContext);
return true;
}
return false;
}
private void coolMethod(String message, CallbackContext callbackContext) {
if (message != null && message.length() > 0) {
callbackContext.success(message);
} else {
callbackContext.error("Expected one non-empty string argument.");
}
}
private void checkReceiveMessage(CallbackContext callbackContext) throws JSONException {
if (this.extraMessage != null && !this.extraMessage.isEmpty()) {
JSONObject json = new JSONObject(this.extraMessage);
callbackContext.success(json);
this.extraMessage = null;
} else {
callbackContext.error("No push message.");
}
}
}
插件JS代码
数据获取的JS
代码,JS
通过Cordova
环境直接调用到Java
的checkReceiveMessage
方法取到数据,并转发到jpush.receiveNotification
事件中:
var exec = require('cordova/exec');
var JPushCustomPlugin = function () {
// noop
};
// 保留测试用
JPushCustomPlugin.prototype.coolMethod = function (arg0, success, error) {
exec(success, error, 'JPushCustomPlugin', 'coolMethod', [arg0]);
};
var receiveMessageInAndroidCallback = function (data) {
var eventData = {
extras: data.n_extras,
alert: data.n_content,
title: data.n_title
};
// 调用
cordova.fireDocumentEvent("jpush.receiveNotification", eventData);
};
JPushCustomPlugin.prototype.checkReceiveMessage = function () {
exec(receiveMessageInAndroidCallback, function (err) {
console.log(err);
}, 'JPushCustomPlugin', 'checkReceiveMessage', []);
};
/**
* 自定义cordova插件
*
* @type {JPushCustomPlugin}
*/
module.exports = new JPushCustomPlugin();
具体使用
需要在极光推送初始化等完成之后,添加JPushCustomPlugin
的消息获取代码:
if (window.JPushCustomPlugin) {
window.JPushCustomPlugin.checkReceiveMessage()
}
这样就完成了,实现了点击消息打开APP
触发jpush.receiveNotification
事件,后续监听逻辑根据实际情况处理。
Github地址
相关文件提交到GitHub
中,方便直接用Cordova
调用GitHub
仓库安装插件
GitHub
地址:https://github.com/fugary/cordova-plugin-jpush-custom
安装方式:
cordova plugin add https://github.com/fugary/cordova-plugin-jpush-custom.git
然后使用,需要在JPush.init()
等JPush
相关代码之后
if (window.JPushCustomPlugin) {
window.JPushCustomPlugin.checkReceiveMessage()
}