ZEGO 即时通讯(ZIM)支持离线推送消息的功能。例如在“单聊”或“群组聊天”时,如果您的程序在后台被冻结、或被系统或用户杀掉,与 ZEGO 服务后台的长连接超时断开后,此时如果您已接入“离线推送”功能,ZEGO 后台会为目标用户发送离线推送的消息。
开发者可以通过集成 ZPNs SDK,与 ZIM SDK 搭配使用,实现离线推送功能。
离线推送方案介绍
ZIM 实现离线推送的方案如下:
- 首先消息接收方(即接收离线消息的用户),开启各厂商的推送通道,向各厂商的推送服务器发送请求,获取 Token。
- 各厂商的推送服务器,将 Token 返回给接收方。
- 接收方生成 PushID,并向 ZIM 服务器发送请求,绑定用户与 PushID 的关系。 开发者如果将 ZPNs SDK 与 ZIM SDK 搭配使用,SDK 内部会自动绑定用户与 PushID 的关系,无需特殊处理;如果单独使用 ZPNs SDK,则需自行对接 ZPNs 服务器、实现绑定逻辑。请注意,同一设备切换 userID 前,请调用 zim.logout 接口,该接口会清除 userID 绑定的 PushID。
- 发送方开始发送消息,消息存储到 ZIM 服务器。
- ZIM 服务器会确认接收方的客户端是否在线。
- 如果接收方的客户端不在线,ZIM 服务器会将消息转发给 ZPNs 服务器。
- ZPNs 服务器将离线消息转发给各厂商的推送服务器。
- 各厂商的服务器将消息通过“离线推送”的方式,推送给接收方;接收方登录后(至少登录一次),即可收到离线消息。
前提条件
在实现“离线推送”功能之前,请确保:
- 开发环境满足以下要求:
- Android Studio 2.1 或以上版本。
- Android SDK 25、Android SDK Build-Tools 25.0.2、Android SDK Platform-Tools 25.x.x 或以上版本。
- Android 9.0 或以上版本 Android 设备或模拟器(推荐使用真机)。
- 已在 ZEGO 控制台 创建项目,获取到了接入 ZIM SDK 服务所需的 AppID、AppSign。ZIM 服务权限不是默认开启的,使用前,请先在 ZEGO 控制台自助开通 ZIM 服务(详情请参考控制台的 服务配置 – 即时通讯 – 开通服务),若无法开通 ZIM 服务,请联系 ZEGO 技术支持开通。
- 已集成 ZIM SDK,详情请参考 快速开始 – 实现基本收发消息 的 “2 集成 SDK”。
实现流程
1 接入第三方厂商离线推送通道
请参考 推送集成指南,集成需要使用到的第三方厂商离线推送 SDK,接入各厂商的离线推送通道。
目前支持华为、小米、OPPO、vivo 和 Google 的推送。
2 集成 ZPNs SDK
2.1 导入 ZPNs SDK
方式一:使用 Maven Central 自动集成 SDK( 2.2.0 及之后
的版本才可使用)
1. 进入项目根目录,打开 “build.gradle” 文件,在 “allprojects” 中加入如下代码。
...
allprojects {
repositories {
mavenCentral()
google()
jcenter()
}
}
2. 进入 “app” 目录,打开 “build.gradle” 文件,在 “dependencies” 中添加 implementation 'im.zego:zpns:x.y.z'
。“x.y.z” 为 SDK 的版本号。
...
dependencies {
...
// x.y.z 请填写具体版本号,如:2.2.0
// 可通过 SDK 发布历史取得最新版本号
implementation 'im.zego:zpns:x.y.z'
}
方式二:复制 SDK 文件手动集成
- 请参考 下载 SDK,下载最新版本的 SDK。
- 将 SDK 包解压至项目目录下,例如 “app/libs”。
- 添加 SDK 引用。进入到 “app” 目录,打开 “build.gradle” 文件。
- 在 dependencies” 节点引入 “libs” 下的 aar。
implementation files('libs/zpns-release.aar')
2.2 设置权限
开发者可以根据实际应用需要,设置应用所需权限。
进入 “app/src/main” 目录,打开 “AndroidManifest.xml” 文件,添加权限。
<!-- ZPNs SDK 必须使用的权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.GET_TASKS" />
3 使用 ZPNs SDK 注册离线推送功能
- 开发者创建新的 Java 类 MyZIMPushReceiver 继承自 ZPNs 中的 ZPNsMessageReceiver 广播类,用于接收厂商推送消息。
<receiver
android:name=".MyZIMPushReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="im.zego.zim.zpns.intent.action.MESSAGE" />
</intent-filter>
</receiver>
- 实现继承 ZPNsMessageReceiver 的广播中的函数,用于向厂商发送相关通知。其中,
关于各大厂商的回调支持情况:
接口名称 | 接口说明 | 厂商支持情况 |
---|---|---|
onThroughMessageReceived | 厂商透传消息回调。各厂商返回的透传消息都会触发该接口,并在此接口抛出通知。 | 小米: APP处于前后台状态下才能收到此回调 vivo: 不支持该回调 华为: APP 处于前后台状态下才能收到此回调 谷歌推送: APP 处于前后台状态下才能收到此回调 oppo: 不支持该回调 |
onNotificationClicked | 厂商通知点击回调。各厂商的通知点击回调,统一在此接口抛出。 | 小米:APP杀死状态下能收到此回调 vivo: 不支持该回调 华为: 不支持该回调 谷歌推送: 不支持该回调 oppo: 不支持该回调 |
onNotificationArrived | 厂商通知展示回调。厂商通知展示回调,统一在此接口抛出。 | 小米:APP处于前后台状态下才能收到此回调 vivo: 不支持该回调 华为: 不支持该回调 谷歌推送: 不支持该回调 oppo: 不支持该回调 |
onRegistered | 厂商注册“离线推送”的结果回调。厂商注册“离线推送”的结果,会统一在此接口抛出,可通过该回调获取到 PushID。 | – |
public class MyZPNsReceiver extends ZPNsMessageReceiver {
// 厂商透传消息回调
@Override
protected void onThroughMessageReceived(Context context, ZPNsMessage message) {
Log.e("MyZPNsReceiver", "onThroughMessageReceived message:" + message.toString());
}
// 厂商通知点击回调
@Override
protected void onNotificationClicked(Context context, ZPNsMessage message) {
Log.e("MyZPNsReceiver", "onNotificationClicked message:" + message.toString());
}
// 厂商通知展示回调
@Override
protected void onNotificationArrived(Context context, ZPNsMessage message) {
Log.e("MyZPNsReceiver", "onNotificationArrived message:" + message.toString());
}
// 厂商注册离线推送结果回调,可通过该回调获取到 Push ID
@Override
protected void onRegistered(Context context, ZPNsRegisterMessage message) {
Log.e("MyZPNsReceiver", "onRegistered: message:" + message.getCommandResult());
}
}
根据离线推送接收端的厂商,开发者应选择不同的 payload 透传字段获取方式,通过 ZPNsMessageReceiver 回调方法中的 ZPNsMessage 对象获取 在上述方法触发时将 ZPNsMessage 对象传给该方法,取出 payload 字段。
static public String getZPNsMessagePayload(ZPNsMessage message){
String payload = "";
switch (message.getPushSource()){
case XIAOMI:
MiPushMessage miMsg = (MiPushMessage) message.getExtras();
payload = miMsg.getExtra().get("payload");
break;
case OPPO:
DataMessage oppoMsg = (DataMessage)message.getExtras();
String extraJson = oppoMsg.getDataExtra();
// 将 extra 转为 map 后,取 key 为 "payload"的 value
break;
case HUAWEI:
RemoteMessage huaweiMsg = (RemoteMessage)message.getExtras();
payload = huaweiMsg.getDataOfMap().get("payload");
break;
case FCM:
com.google.firebase.messaging.RemoteMessage remoteMessage = (com.google.firebase.messaging.RemoteMessage)message.getExtras();
payload = remoteMessage.getData().get("payload");
break;
}
return payload;
}
- 配置第三方推送通道
根据前提条件集成的第三方厂商离线推送 SDK,调用 enableHWPush
/enableMiPush
/enableOppoPush
/enableVivoPush
接口,启用各厂商的推送功能,然后调用 setPushConfig
接口,配置第三方推送通道。
ZPNsConfig zpnsConfig = new ZPNsConfig();
zpnsConfig.enableFCMPush(); // FCM
zpnsConfig.enableHWPush("HW_APP_ID"); // 华为
zpnsConfig.enableMiPush("MI_APPID", "MI_APPKEY"); // 小米
zpnsConfig.enableOppoPush("OPPO_APP_ID", "OPPO_APP_KEY", "OPPO_APP_SECRET"); // OPPO
zpnsConfig.enableVivoPush("VIVO_APP_ID", "VIVO_APP_KEY"); // vivo
ZPNsManager.getInstance().setPushConfig(zpnsConfig);
- 注册离线推送功能
ZPNsManager.getInstance().registerPush(this.getApplication());
注册离线推送功能后,可以通过继承 ZPNsMessageReceiver
类中的 onRegistered
回调,获取到离线推送的 pushID
,向指定设备推送离线消息。
- 如果不再需要离线推送功能,开发者可以调用
unregisterPush
接口,注销该功能,注销后用户将不再能收到推送消息。
ZPNsManager.getInstance().unregisterPush();
4 使用 ZIM SDK 实现离线推送功能
ZIM 支持在发送单聊消息、发送群组消息时,使用离线推送消息的功能。
4.1 发送单聊消息时使用离线推送功能
1. 首先开发者需要通过 ZIMPushConfig
对象,设置离线推送标题、内容、以及其它自定义属性。
ZIMPushConfig pushConfig = new ZIMPushConfig();
pushConfig.title = "离线推送标题";
pushConfig.content = "离线推送内容";
pushConfig.payload = "自定义透传字段,非必填";
pushConfig.resourcesID = "资源ID";
2. 后通过 ZIMMessageSendConfig
对象的 pushConfig
参数,配置离线消息的相关配置等。
ZIMMessageSendConfig sentConfig = new ZIMMessageSendConfig();
sentConfig.pushConfig = pushConfig;
3. 发送方调用 sendMessage
,传入 “sentConfig”,向接收方发送单聊消息。
zim.sendMessage(textMessage, "myUserID", ZIMConversationType.PEER, sentConfig, new ZIMMessageSentCallback() {
@Override
public void onMessageSent(ZIMMessage message, ZIMError errorInfo) {
}
@Override
public void onMessageAttached(ZIMMessage message) {
}
});
4. 接收方如果处于离线状态,将会在上线后,接收到发送方之前发送的离线消息。
4.2 发送群组消息时使用离线推送功能
1. 开发者通过 ZIMPushConfig
对象,设置离线推送标题、内容、以及其它自定义属性。
ZIMTextMessage textMessage = new ZIMTextMessage();
ZIMPushConfig pushConfig = new ZIMPushConfig();
pushConfig.title = "离线推送标题";
pushConfig.content = "离线推送内容";
pushConfig.payload = "自定义透传字段,非必填";
pushConfig.resourcesID = "资源ID";
2. 然后通过 ZIMMessageSendConfig
对象的 pushConfig
参数,配置离线消息的相关配置等。
ZIMMessageSendConfig sentConfig = new ZIMMessageSendConfig();
sentConfig.pushConfig = pushConfig;
3. 发送方调用 sendMessage
,传入 “sentConfig”,向群组内的所有用户发送消息。
zim.sendMessage(textMessage, "myGroupID", ZIMConversationType.GROUP, sentConfig, new ZIMMessageSentCallback() {
@Override
public void onMessageSent(ZIMMessage message, ZIMError errorInfo) {
}
@Override
public void onMessageAttached(ZIMMessage message) {
}
});
4. 群组内的用户,如果有人处于离线状态,将会在上线后,接收到发送方之前发送的群组离线消息。
在线调试
集成 ZPNs SDK 和获取 Push ID 后,您可以在 ZEGO 控制台 在线调试 ZIM 离线推送功能,详情请参考控制台的 ZIM 离线推送调试。
本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/im/39223.html