即时通讯 IM 支持集成第三方厂商的消息推送服务,为 Android 开发者提供低延时、高送达、高并发、不侵犯用户个人数据的离线消息推送服务。
当客户端应用进程被关闭等原因导致用户离线,即时通讯 IM 会通过第三方厂商的消息推送服务向该离线用户的设备推送消息通知。当用户再次上线时,会收到离线期间所有消息。
本文介绍如何在客户端应用中实现各厂商的推送服务。
消息推送流程如下:
开发者通过声网控制台配置 App 的推送证书,需填写证书名称及推送密钥等信息。该步骤须在登录即时通讯 IM SDK 成功后进行。
证书名称是声网即时通讯服务器用于判断目标设备使用哪种推送通道的唯一条件,因此必须确保与 Android 终端设备上传的证书名称一致。
各厂商推送服务的使用条件如下:
SDK 内部会按照这个顺序检测设备的推送支持情况。
如果未设置第三方推送或者不满足使用第三方推送的条件,即时通讯 IM SDK 会通过一些保活手段尽可能的保持与声网服务器的长连接,以确保消息及时送达。
此外,使用消息推送前,需要你在对应的手机厂商推送服务上注册项目,并将设备的推送证书上传到声网控制台。
为防止代码混淆,在你的混淆规则中添加如下代码:
-dontwarn io.agora.push.***
-keep class io.agora.push.*** {*;}
除此之外,你还需要添加第三方推送的混淆规则,详见各厂商的开发者平台文档。
在 Firebase 控制台添加 Firebase,详见 FCM 的官网介绍。
将 Firebase SDK 添加到你的应用后,在 Firebase 控制台的 Project settings
页面,选择 Cloud Messaging
标签,查看 Server ID
和 Server Key
。
a. 登录声网控制台,点击左侧导航栏的项目管理。
b. 选择需要开通即时通讯服务的项目,点击配置。
c. 在服务配置页面,点击即时通讯中的配置。
d. 选择功能配置 > 推送证书。在证书管理页面,点击添加推送证书,在弹出的对话框中选择
谷歌,将证书名称设置为 FCM 的发送者 ID,推送秘钥设置为 FCM 的服务器密钥。即时通讯 IM 支持 FCM 的旧版证书和 v1 版证书。
在项目根目录下的 build.gradle
中添加 FCM 服务插件。
dependencies {
// FCM 推送
classpath 'com.google.gms:google-services:4.3.8'
}
在项目的 module 的 gradle 文件中(通常为 /app/build.gradle )配置 FCM 库的依赖。
dependencies {
// ...
// FCM:导入 Firebase BoM
implementation platform('com.google.firebase:firebase-bom:28.4.1')
// FCM:声明 FCM 的依赖项
// 使用 BoM 时,不要在 Firebase 库依赖中指定版本
implementation 'com.google.firebase:firebase-messaging'
}
// 添加下行代码:
apply plugin: 'com.google.gms.google-services' // Google 服务插件
同步应用后,继承 FirebaseMessagingService
的服务,并将其在 AndroidManifest.xml
中注册。
<service
android:name=".java.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
在即时通讯 IM SDK 中启用 FCM。
ChatOptions options = new ChatOptions();
...
PushConfig.Builder builder = new PushConfig.Builder(this);
// 替换为你的 FCM 发送方的用户 ID
builder.enableFCM("Your FCM sender id");
// 将 pushconfig 设置到 ChatOptions 中
options.setPushConfig(builder.build());
// 初始化即时通讯 IM SDK
ChatClient.getInstance().init(this, options);
// 即时通讯 IM SDK 初始化后
PushHelper.getInstance().setPushListener(new PushListener() {
@Override
public void onError(PushType pushType, long errorCode) {
EMLog.e("PushClient", "Push client occur a error: " + pushType + " - " + errorCode);
}
@Override
public boolean isSupportPush(PushType pushType, PushConfig pushConfig) {
// 设置是否支持 FCM
if(pushType == PushType.FCM) {
return GoogleApiAvailabilityLight.getInstance().isGooglePlayServicesAvailable(MainActivity.this)
== ConnectionResult.SUCCESS;
}
return super.isSupportPush(pushType, pushConfig);
}
});
即时通讯 IM SDK 登录成功后,上传 FCM 的 device token。
// 查看是否支持 FCM
if(GoogleApiAvailabilityLight.getInstance().isGooglePlayServicesAvailable(MainActivity.this) != ConnectionResult.SUCCESS) {
return;
}
FirebaseMessaging.getInstance().getToken().addOnCompleteListener(new OnCompleteListener<String>() {
@Override
public void onComplete(@NonNull Task<String> task) {
if (!task.isSuccessful()) {
EMLog.d("PushClient", "Fetching FCM registration token failed:"+task.getException());
return;
}
// 获取新的 FCM 注册 token
String token = task.getResult();
ChatClient.getInstance().sendFCMTokenToServer(token);
}
});
监控 device token 生成。
重写 FirebaseMessagingService
中的 onNewToken
方法,device token 更新后及时更新到即时通讯 IM SDK。
public class FCMMSGService extends FirebaseMessagingService {
private static final String TAG = "FCMMSGService";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if (remoteMessage.getData().size() > 0) {
String message = remoteMessage.getData().get("alert");
Log.d(TAG, "onMessageReceived: " + message);
}
}
@Override
public void onNewToken(@NonNull String token) {
Log.i("MessagingService", "onNewToken: " + token);
// 若要对该应用实例发送消息或管理服务端的应用订阅,将 FCM 注册 token 发送至你的应用服务器。
if(ChatClient.getInstance().isSdkInited()) {
ChatClient.getInstance().sendFCMTokenToServer(token);
}
}
}
在华为开发者后台创建 Android 应用,开启消息推送服务,并获取 App ID 和 Secret Key。参考文档详见华为推送服务。
登录声网控制台,点击左侧导航栏的项目管理。
选择需要开通即时通讯服务的项目,点击配置。
在服务配置页面,点击即时通讯中的配置。
选择功能配置 > 推送证书。在证书管理页面,点击添加推送证书,在弹出的对话框中选择华为,并配置如下字段:
集成 HMS Core SDK,详见华为官方集成文档。
在 AndroidManifest.xml
文件中注册 HmsMessageService
服务。
<!--华为 HMS Config-->
<service android:name=".service.HMSPushService"
android:exported="false">
<intent-filter>
<action android:name="com.huawei.push.action.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- huawei push end -->
获取消息推送 Token,详见获取和注销推送 Token,并参考如下代码,将推送 Token 上传到即时通讯 IM 服务器。
public class HMSPushService extends HmsMessageService {
@Override
public void onNewToken(String token) {
if(token != null && !token.equals("")){
//没有失败回调,假定 token 失败时 token 为 null
EMLog.d("HWHMSPush", "service register huawei hms push token success token:" + token);
ChatClient.getInstance().sendHMSPushTokenToServer(token);
}else{
EMLog.e("HWHMSPush", "service register huawei hms push token fail!");
}
}
}
ChatOptions options = new ChatOptions();
...
PushConfig.Builder builder = new PushConfig.Builder(this);
builder..enableHWPush();
// 将 pushconfig 设置为 ChatOptions。
options.setPushConfig(builder.build());
// 初始化即时通讯 IM SDK。
ChatClient.getInstance().init(this, options);
在小米开放平台创建 Android 应用,开启消息推送服务,并获取 app ID 和 Secret Key。详见推送服务接入指南。
登录声网控制台,点击左侧导航栏项目管理。
选择需要开通即时通讯服务的项目,点击配置。
在服务配置页面,点击即时通讯中的配置。
选择功能配置 > 推送证书。在证书管理页面,点击添加推送证书,在弹出的对话框中选择小米,并配置如下字段:
添加如下权限:
<!--注:以下三个权限在 4.8.0 及以上版本不再依赖-->
<!-- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />-->
<!-- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />-->
<!-- <uses-permission android:name="android.permission.READ_PHONE_STATE" />-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE"/>
<permission android:name="com.xiaomi.mipushdemo.permission.MIPUSH_RECEIVE"
android:protectionLevel="signature" /> <!--这里 com.xiaomi.mipushdemo 改成 app 的包名-->
<uses-permission android:name="com.xiaomi.mipushdemo.permission.MIPUSH_RECEIVE" /><!--这里 com.xiaomi.mipushdemo 改成 app 的包名-->
配置推送的 service
和 receiver
:
<service
android:name="com.xiaomi.push.service.XMPushService"
android:enabled="true"
android:process=":pushservice" />
<!--注:此服务必须在 3.0.1 版本以后(包括 3.0.1 版本)加入-->
<service
android:name="com.xiaomi.push.service.XMJobService"
android:enabled="true"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE"
android:process=":pushservice" />
<!--注:com.xiaomi.xmsf.permission.MIPUSH_RECEIVE 这里的包名不能改为 app 的包名-->
<service
android:name="com.xiaomi.mipush.sdk.PushMessageHandler"
android:enabled="true"
android:exported="true"
android:permission="com.xiaomi.xmsf.permission.MIPUSH_RECEIVE" />
<!--注:此服务必须在 2.2.5 版本以后(包括 2.2.5 版本)加入-->
<service
android:name="com.xiaomi.mipush.sdk.MessageHandleService"
android:enabled="true" />
<receiver
android:name="com.xiaomi.push.service.receivers.NetworkStatusReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver
android:name="com.xiaomi.push.service.receivers.PingReceiver"
android:exported="false"
android:process=":pushservice">
<intent-filter>
<action android:name="com.xiaomi.push.PING_TIMER" />
</intent-filter>
</receiver>
自定义一个继承自即时通讯 IM SDK 中 EMMiMsgReceiver
类的 BroadcastReceiver
并注册到 AndroidManifest.xml
文件中。
<receiver android:name=".common.receiver.MiMsgReceiver">
<intent-filter>
<action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE" />
</intent-filter>
<intent-filter>
<action android:name="com.xiaomi.mipush.MESSAGE_ARRIVED" />
</intent-filter>
<intent-filter>
<action android:name="com.xiaomi.mipush.ERROR" />
</intent-filter>
</receiver>
在 SDK 初始化时配置启用小米推送。
ChatOptions options = new ChatOptions();
...
PushConfig.Builder builder = new PushConfig.Builder(this);
builder..enableMiPush(String appId, String appKey);
//将 pushconfig 设置为 ChatOptions。
options.setPushConfig(builder.build());
// 初始化即时通讯 IM SDK。
ChatClient.getInstance().init(this, options);
即时通讯 IM SDK 中已经集成了 OPPO 推送相关逻辑,你还需要完成以下步骤:
在 OPPO 开发者后台创建应用,开启推送服务,并上传对应的证书指纹。详见 OPPO 官方介绍:OPPO 推送服务集成。
登录声网控制台,点击左侧导航栏的项目管理。
选择需要开通即时通讯服务的项目,点击配置。
在服务配置页面,点击即时通讯中的配置。
选择功能配置 > 推送证书。在证书管理页面,点击添加推送证书,在弹出的对话框中选择OPPO。
设置对话框中的参数名称。
对于证书名称和应用包名,分别填入 OPPO 开发者后台创建的应用的 appkey
和程序的包名
。对于推送秘钥,在 OPPO 推送平台 > 配置管理 > 应用配置 页面查看 mastersecret
。
在 OPPO 推送官网下载推送 SDK 包,将 jar 包放到 libs 目录下并同步。也可以直接使用即时通讯 IM Android Demo 中集成的 OPPO 推送的 jar 包。
配置 AndroidManifest.xml
。
<!-- OPPO 推送配置 start -->
<uses-permission android:name="com.coloros.mcs.permission.RECIEVE_MCS_MESSAGE"/>
<uses-permission android:name="com.heytap.mcs.permission.RECIEVE_MCS_MESSAGE"/>
<!-- OPPO 推送配置 end -->
<!-- OPPO 推送配置 start -->
<service
android:name="com.heytap.msp.push.service.CompatibleDataMessageCallbackService"
android:permission="com.coloros.mcs.permission.SEND_MCS_MESSAGE">
<intent-filter>
<action android:name="com.coloros.mcs.action.RECEIVE_MCS_MESSAGE"/>
</intent-filter>
</service> <!--兼容 Q 以下版本-->
<service
android:name="com.heytap.msp.push.service.DataMessageCallbackService"
android:permission="com.heytap.mcs.permission.SEND_PUSH_MESSAGE">
<intent-filter>
<action android:name="com.heytap.mcs.action.RECEIVE_MCS_MESSAGE"/>
<action android:name="com.heytap.msp.push.RECEIVE_MCS_MESSAGE"/>
</intent-filter>
</service> <!--兼容 Q 版本-->
<!-- OPPO 推送配置 end -->
在 SDK 初始化时,配置启用 OPPO 推送。
ChatOptions options = new ChatOptions();
...
PushConfig.Builder builder = new PushConfig.Builder(this);
builder.enableOppoPush(String appKey,String appSecret);
// 将 pushconfig 设置为 ChatOptions
options.setPushConfig(builder.build());
// 初始化 IM SDK
ChatClient.getInstance().init(this, options);
HeytapPushManager.init(context, true);
即时通讯 IM SDK 中已经集成了 VIVO 推送(基于 vivo_push_v2.3.1.jar
)相关逻辑,你还需要完成以下步骤:
在 VIVO 开发者后台创建应用,开启推送服务,并上传对应的证书指纹。详见 VIVO 官方介绍: VIVO 推送服务集成。
登录声网控制台,点击左侧导航栏的项目管理。
选择需要开通即时通讯服务的项目,点击配置。
在服务配置页面,点击即时通讯中的配置。
选择功能配置 > 推送证书。在证书管理页面,点击添加推送证书。在弹出的对话框中选择 VIVO,然后输入你在 VIVO 开发者后台创建的应用的 APP ID
,APP KEY
和 APP SECRET
以及程序的 包名
。
配置 VIVO 推送 jar 包: 在 VIVO 推送官网下载推送 SDK 包,将 jar 包放到 libs 目录下并同步。也可以直接使用即时通讯 IM Android Demo 中集成的 VIVO 推送的 jar 包。
配置 AndroidManifest.xml
。
推送服务需要的 service 和 receiver,并且需要配置 VIVO 的 app_id 和 app_key:
<!-- VIVO 推送配置 start -->
<!--VIVO Push SDK 的版本信息-->
<meta-data
android:name="sdk_version_vivo"
android:value="484"/>
<meta-data
android:name="local_iv"
android:value="MzMsMzQsMzUsMzYsMzcsMzgsMzksNDAsNDEsMzIsMzgsMzcsMzYsMzUsMzQsMzMsI0AzNCwzMiwzMywzNywzMywzNCwzMiwzMywzMywzMywzNCw0MSwzNSwzNSwzMiwzMiwjQDMzLDM0LDM1LDM2LDM3LDM4LDM5LDQwLDQxLDMyLDM4LDM3LDMzLDM1LDM0LDMzLCNAMzQsMzIsMzMsMzcsMzMsMzQsMzIsMzMsMzMsMzMsMzQsNDEsMzUsMzIsMzIsMzI" />
<service
android:name="com.vivo.push.sdk.service.CommandClientService"
android:permission="com.push.permission.UPSTAGESERVICE"
android:exported="true" />
<activity
android:name="com.vivo.push.sdk.LinkProxyClientActivity"
android:exported="false"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<!--推送配置项-->
<meta-data
android:name="com.vivo.push.api_key"
android:value="开发者自己申请的 appKey" />
<meta-data
android:name="com.vivo.push.app_id"
android:value="开发者自己申请的 appId" />
<receiver android:name="io.agora.push.platform.vivo.VivoMsgReceiver" >
<intent-filter>
<!-- 接收推送消息 -->
<action android:name="com.vivo.pushclient.action.RECEIVE" />
</intent-filter>
</receiver>
<!-- VIVO 推送配置 end -->
在 SDK 初始化的时候,配置启用 VIVO 推送。
ChatOptions options = new ChatOptions();
...
PushConfig.Builder builder = new PushConfig.Builder(this);
builder.enableVivoPush();
// 将 pushconfig 设置为 ChatOptions
options.setPushConfig(builder.build());
// 初始化 IM SDK
ChatClient.getInstance().init(this, options);
VIVO 设备安装应用后默认没有打开允许通知权限,测试前需首先在设置中打开该应用的允许通知权限。
详情请参见 VIVO 推送官方文档。
在魅族开发者后台创建应用,开启推送服务,并上传对应的证书指纹。详见魅族官方介绍:Flyme 推送服务集成。
登录声网控制台,点击左侧导航栏的项目管理。
选择需要开通即时通讯服务的项目,点击配置。
在服务配置页面,点击即时通讯中的配置。
选择功能配置 > 推送证书。在证书管理页面,点击添加推送证书,在弹出的对话框中选魅族,然后输入你在 flyme 推送平台创建的应用的 APP ID
和 APP SECRET
以及程序的 包名
。
配置魅族推送 jar 包:
在 app level/build.gradle 中添加依赖。
dependencies{
// 该 aar 托管在 jcenter 中,请确保当前项目已配置 jcenter 仓库。
implementation 'com.meizu.flyme.internet:push-internal:3.7.0@aar'
}
配置 AndroidManifest.xml
。
推送服务需要的权限列表:
<!-- 魅族推送配置 start-->
<!-- 兼容 flyme5.0 以下版本,魅族内部集成 pushSDK 必填,不然无法收到消息-->
<uses-permission android:name="com.meizu.flyme.push.permission.RECEIVE" />
<permission
android:name="${applicationId}.push.permission.MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="${applicationId}.push.permission.MESSAGE" />
<!-- 兼容 flyme3.0 配置权限-->
<uses-permission android:name="com.meizu.c2dm.permission.RECEIVE" />
<permission
android:name="${applicationId}.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
<!-- 魅族推送配置 end-->
推送服务需要的 receiver:
<!-- MEIZU 推送配置 start -->
<receiver android:name="io.agora.push.platform.meizu.MzMsgReceiver">
<intent-filter>
<!-- 接收 push 消息 -->
<action android:name="com.meizu.flyme.push.intent.MESSAGE"
/>
<!-- 接收 register 消息 -->
<action
android:name="com.meizu.flyme.push.intent.REGISTER.FEEDBACK" />
<!-- 接收 unregister 消息-->
<action
android:name="com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK"/>
<!-- 兼容低版本 Flyme3 推送服务配置 -->
<action android:name="com.meizu.c2dm.intent.REGISTRATION"
/>
<action android:name="com.meizu.c2dm.intent.RECEIVE" />
<category android:name="${applicationId}"></category>
</intent-filter>
</receiver>
<!-- MEIZU 推送配置 end -->
ChatOptions options = new ChatOptions();
...
PushConfig.Builder builder = new PushConfig.Builder(this);
builder.enableMeiZuPush(String appId,String appKey);
// 将 pushconfig 设置为 ChatOptions
options.setPushConfig(builder.build());
// 初始化 IM SDK
ChatClient.getInstance().init(this, options);
为优化用户在处理大量推送通知时的体验,即时通讯 IM 在 app 和会话层面提供了推送通知和免打扰模式的细粒度选项。
推送通知方式
推送通知方式参数 |
描述 |
应用范围 |
ALL |
接收所有离线消息的推送通知。 |
App 或单聊/群聊会话 |
MENTION_ONLY |
仅接收提及消息的推送通知。 该参数推荐在群聊中使用。若提及一个或多个用户,需在创建消息时对 `ext` 字段传 "em_at_list":["user1", "user2" ...];若提及所有人,对该字段传 "em_at_list":"all"。 |
|
NONE |
不接收离线消息的推送通知。 |
会话级别的推送通知方式设置优先于 app 级别的设置,未设置推送通知方式的会话默认采用 app 的设置。
例如,假设 app 的推送方式设置为 MENTION_ONLY
,而指定会话的推送方式设置为 ALL
。你会收到来自该会话的所有推送通知,而对于其他会话来说,你只会收到提及你的消息的推送通知。
免打扰模式
你可以在 app 级别指定免打扰时间段和免打扰时长,即时通讯 IM 在这两个时间段内不发送离线推送通知。若既设置了免打扰时间段,又设置了免打扰时长,免打扰模式的生效时间为这两个时间段的累加。
免打扰时间参数的说明如下表所示:
免打扰时间参数 | 描述 | 应用范围 |
---|---|---|
SILENT_MODE_INTERVAL |
免打扰时间段,精确到分钟,格式为 HH:MM-HH:MM,例如 08:30-10:00。该时间为 24 小时制,免打扰时间段的开始时间和结束时间中的小时数和分钟数的取值范围分别为 [00,23] 和 [00,59]。免打扰时间段的设置说明如下:
|
仅用于 app 级别,对单聊或群聊会话不生效。 |
SILENT_MODE_DURATION |
免打扰时长,单位为毫秒。免打扰时长的取值范围为 [0,604800000],0 表示该参数无效,604800000 表示免打扰模式持续 7 天。与免打扰时间段的设置长久有效不同,该参数为一次有效。 |
App 或单聊/群聊会话。 |
若在免打扰时段或时长生效期间需要对指定用户推送消息,需设置强制推送。
推送通知方式与免打扰时间设置之间的关系
对于 app 和 app 中的所有会话,免打扰模式的设置优先于推送通知方式的设置。例如,假设在 app 级别指定了免打扰时间段,并将指定会话的推送通知方式设置为 ALL
。免打扰模式与推送通知方式的设置无关,即在指定的免打扰时间段内,你不会收到任何推送通知。
或者,假设为会话指定了免打扰时间段,而 app 没有任何免打扰设置,并且其推送通知方式设置为 ALL
。在指定的免打扰时间段内,你不会收到来自该会话的任何推送通知,而所有其他会话的推送保持不变。
你可以调用 setSilentModeForAll
设置 app 级别的推送通知,并通过指定 SilentModeParam
字段设置推送通知方式和免打扰模式,如下代码示例所示:
//设置推送通知方式为 `MENTION_ONLY`。
SilentModeParam param = new SilentModeParam(SilentModeParam.SilentModeParamType.REMIND_TYPE)
.setRemindType(PushManager.PushRemindType.MENTION_ONLY);
//设置离线推送免打扰时长为 15 分钟。
SilentModeParam param = new SilentModeParam(SilentModeParam.SilentModeParamType.SILENT_MODE_DURATION)
.setSilentModeDuration(15);
//设置离线推送的免打扰时间段为 8:30 至 15:00。
SilentModeParam param = new SilentModeParam(SilentModeParam.SilentModeParamType.SILENT_MODE_INTERVAL)
.setSilentModeInterval(new SilentModeTime(8, 30), new SilentModeTime(15, 0));
//设置 app 的离线推送通知。
ChatClient.getInstance().pushManager().setSilentModeForAll(param, new ValueCallBack<SilentModeResult>(){});
你可以调用 getSilentModeForAll
获取 app 级别的推送通知设置,如以下代码示例所示:
ChatClient.getInstance().pushManager().getSilentModeForAll(new ValueCallBack<SilentModeResult>(){
@Override
public void onSuccess(SilentModeResult result) {
// 获取 app 的推送通知方式的设置。
PushManager.PushRemindType remindType = result.getRemindType();
// 获取 app 的离线推送免打扰过期的 Unix 时间戳。
long timestamp = result.getExpireTimestamp();
// 获取 app 的离线推送免打扰时间段的开始时间。
SilentModeTime startTime = result.getSilentModeStartTime();
startTime.getHour(); // 免打扰时间段的开始时间中的小时数。
startTime.getMinute(); // 免打扰时间段的开始时间中的分钟数。
// 获取 app 的离线推送免打扰时间段的结束时间。
SilentModeTime endTime = result.getSilentModeEndTime();
endTime.getHour(); // 免打扰时间段的结束时间中的小时数。
endTime.getMinute(); // 免打扰时间段的结束时间中的分钟数。
}
@Override
public void onError(int error, String errorMsg) {}
});
你可以调用 setSilentModeForConversation
方法设置指定会话的推送通知,并通过指定 SilentModeParam
字段设置推送通知方式和免打扰模式,如以下代码示例所示:
//设置推送通知方式为 `MENTION_ONLY`。
SilentModeParam param = new SilentModeParam(SilentModeParam.SilentModeParamType.REMIND_TYPE)
.setRemindType(PushManager.PushRemindType.MENTION_ONLY);
//设置离线推送免打扰时长为 15 分钟。
SilentModeParam param = new SilentModeParam(SilentModeParam.SilentModeParamType.SILENT_MODE_DURATION)
.setSilentDuration(15);
//设置会话的离线推送免打扰模式。目前,暂不支持设置会话免打扰时间段。
ChatClient.getInstance().pushManager().setSilentModeForConversation(conversationId, conversationType, param, new ValueCallBack<SilentModeResult>(){});
你可以调用 getSilentModeForConversation
方法获取指定会话的推送通知设置,如以下代码示例所示:
ChatClient.getInstance().pushManager().getSilentModeForConversation(conversationId, conversationType, new ValueCallBack<SilentModeResult>(){
@Override
public void onSuccess(SilentModeResult result) {
// 获取指定会话是否设置了推送通知方式。
boolean enable = result.isConversationRemindTypeEnabled();
// 检查会话是否设置了推送通知方式。
if(enable){
//获取会话的推送通知方式。
PushManager.PushRemindType remindType = result.getRemindType();
}
// 获取会话的离线推送免打扰过期 Unix 时间戳。
long timestamp = result.getExpireTimestamp();
}
@Override
public void onError(int error, String errorMsg) {}
});
你可以在每次调用中最多获取 20 个会话的推送通知设置。
如果会话继承了 app 设置或其推送通知设置已过期,则返回的字典不包含此会话。
你可以调用 getSilentModeForConversations
方法获取多个会话的推送通知设置,如以下示例代码所示:
ChatClient.getInstance().pushManager().getSilentModeForConversations(conversationList, new ValueCallBack<Map<String, SilentModeResult>>(){
@Override
public void onSuccess(Map<String, SilentModeResult> value) {}
@Override
public void onError(int error, String errorMsg) {}
});
你可以调用 clearRemindTypeForConversation
方法清除指定会话的推送通知方式的设置。清除后,默认情况下,该会话会继承 app 的设置。
以下代码示例显示了如何清除会话的推送通知方式:
ChatClient.getInstance().pushManager().clearRemindTypeForConversation(conversationId, conversationType, new CallBack(){});
你可以调用 updatePushNickname
方法设置推送通知中显示的昵称,如以下代码示例所示:
// 需要异步处理。
ChatClient.getInstance().pushManager().updatePushNickname("pushNickname");
你也可以调用 updatePushDisplayStyle
方法设置推送通知的显示样式,如下代码示例所示:
// `DisplayStyle` 设置为简单样式 `SimpleBanner`,只显示 "你有一条新消息"。若要显示消息内容,需设置为 `MessageSummary`。
PushManager.DisplayStyle displayStyle = PushManager.DisplayStyle.SimpleBanner;
// 需要异步处理。
ChatClient.getInstance().pushManager().updatePushDisplayStyle(displayStyle);
你可以调用 getPushConfigsFromServer
方法获取推送通知中的显示属性,如以下代码示例所示:
PushConfigs pushConfigs = ChatClient.getInstance().pushManager().getPushConfigsFromServer();
// 获取推送显示昵称。
String nickname = pushConfigs.getDisplayNickname();
// 获取推送通知的显示样式。
PushManager.DisplayStyle style = pushConfigs.getDisplayStyle();
如果用户启用自动翻译功能并发送消息,SDK 会同时发送原始消息和翻译后的消息。
推送通知与翻译功能协同工作。作为接收方,你可以设置你在离线时希望接收的推送通知的首选语言。如果翻译消息的语言符合你的设置,则翻译消息显示在推送通知中;否则,将显示原始消息。
以下示例代码显示如何设置和获取推送通知的首选语言:
// 设置离线推送的首选语言。
ChatClient.getInstance().pushManager().setPreferredNotificationLanguage("en", new CallBack(){});
// 获取设置的离线推送的首选语言。
ChatClient.getInstance().pushManager().getPreferredNotificationLanguage(new ValueCallBack<String>(){});
即时通讯 IM 支持自定义推送通知模板。使用前,你可以参考以下步骤为用户创建和提供推送模板:
登录声网控制台,点击左侧导航栏中的项目管理。
在项目管理 页面,找到开启即时通讯 IM 的项目,点击配置。
在服务配置页面,点击 即时通讯IM 框的配置。
在左侧导航栏,选择功能配置 > 推送模板并单击添加推送模板,在弹出的对话框中配置字段,如下图所示。
创建推送模板后,用户可以在发送消息时选择使用此模板,代码示例如下所示。
// 下面以文本消息为例,其他类型的消息设置方法相同。
ChatMessage message = ChatMessage.createSendMessage(ChatMessage.Type.TXT);
TextMessageBody txtBody = new TextMessageBody("message content");
message.setTo("6006");
// 将在声网控制台上创建的推送模板设置为默认推送模板。
JSONObject pushObject = new JSONObject();
JSONArray titleArgs = new JSONArray();
JSONArray contentArgs = new JSONArray();
try {
// 设置推送模板名称。
pushObject.put("name", "test7");
// 设置填写模板标题的 value 数组。
titleArgs.put("value1");
//...
pushObject.put("title_args", titleArgs);
// 设置填写模板内容的 value 数组。
contentArgs.put("value1");
//...
pushObject.put("content_args", contentArgs);
} catch (JSONException e) {
e.printStackTrace();
}
// 将推送模板添加到消息中。
message.setAttribute("em_push_template", pushObject);
// 设置消息状态回调。
message.setMessageStatusCallback(new CallBack() {...});
// 发送消息。
ChatClient.getInstance().chatManager().sendMessage(message);
在收到推送消息时,解析推送字段。
参数 | 描述 |
---|---|
t |
消息推送接收方的用户 ID。 |
f |
消息推送发送方的用户 ID。 |
m |
消息 ID。消息唯一标识符。 |
g |
群组 ID,仅当消息为群组消息时,该字段存在。 |
e |
用户自定义扩展字段。 |
其中 e 为用户自定义扩展,而数据来源为 em_apns_ext
或 em_apns_ext.extern
。
规则如下:
extern
不存在时,e
内容为 em_apns_ext
下推送服务未使用字段,即除 em_push_title
,em_push_content
,em_push_name
,em_push_channel_id
,em_huawei_push_badge_class
之外的其他字段。extern
存在时,使用 extern
下字段。重写 FirebaseMessagingService.onMessageReceived
方法可以在 RemoteMessage
对象中获取自定义扩展:
public class FCMMSGService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if (remoteMessage.getData().size() > 0) {
String f = remoteMessage.getData().get("f");
String t = remoteMessage.getData().get("t");
String m = remoteMessage.getData().get("m");
String g = remoteMessage.getData().get("g");
Object e = remoteMessage.getData().get("e");
}
}
}
public class SplashActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
Bundle extras = getIntent().getExtras();
if (extras != null) {
String t = extras.getString("t");
String f = extras.getString("f");
String m = extras.getString("m");
String g = extras.getString("g");
Object e = extras.get("e");
//handle
}
}
}
重写 EMMiMsgReceiver.onNotificationMessageClicked
方法可以在 MiPushMessage
对象中获取自定义扩展:
public class MiMsgReceiver extends EMMiMsgReceiver {
@Override
public void onNotificationMessageClicked(Context context, MiPushMessage miPushMessage) {
String extStr = miPushMessage.getContent();
JSONObject extras = new JSONObject(extStr);
if (extras !=null ){
String t = extras.getString("t");
String f = extras.getString("f");
String m = extras.getString("m");
String g = extras.getString("g");
Object e = extras.get("e");
//handle
}
}
}
重写 VivoMsgReceiver.onNotificationMessageClicked
方法可以在 UPSNotificationMessage
对象中获取自定义扩展:
public class MyVivoMsgReceiver extends VivoMsgReceiver {
@Override
public void onNotificationMessageClicked(Context context, UPSNotificationMessage upsNotificationMessage) {
Map<String, String> map = upsNotificationMessage.getParams();
if(!map.isEmpty()) {
String t = map.get("t");
String f = map.get("f");
String m = map.get("m");
String g = map.get("g");
Object e = map.get("e");
}
}
}
解析方式同华为。
解析方式同华为。
参考如下代码,向推送中添加你自己的业务字段以满足业务需求,比如通过这条推送跳转到应用的某个页面(需要应用在前台运行时)。
// 本示例以文本消息为例,图片和文件等消息类型的设置方法相同
ChatMessage message = ChatMessage.createSendMessage(ChatMessage.Type.TXT);
TextMessageBody txtBody = new TextMessageBody("message content");
// 设置消息接收方:单聊为对端用户的用户 ID;群聊为群组 ID;聊天室聊天为聊天室 ID。
message.setTo("toChatUsername");
// 设置自定义推送提示
JSONObject extObject = new JSONObject();
try {
extObject.put("test1", "test 01");
} catch (JSONException e) {
e.printStackTrace();
}
// 将推送扩展设置到消息中
message.setAttribute("em_apns_ext", extObject);
// 设置消息体
message.addBody(txtBody);
// 设置消息回调
message.setMessageStatusCallback(new CallBack() {...});
// 发送消息
ChatClient.getInstance().chatManager().sendMessage(message);
参数 | 描述 |
---|---|
txtBody |
推送消息内容。 |
toChatUsername |
消息接收方的用户 ID。 |
em_apns_ext |
消息扩展字段。该字段名固定,不可修改。 |
test1 |
用户添加的自定义 key。 |
参考如下代码,自定义推送消息显示内容:
// 本示例以文本消息为例,图片和文件等消息类型的设置方法相同
ChatMessage message = ChatMessage.createSendMessage(ChatMessage.Type.TXT);
TextMessageBody txtBody = new TextMessageBody("message content");
// 设置消息接收方:单聊为对端用户的用户 ID;群聊为群组 ID;聊天室聊天为聊天室 ID。
message.setTo("toChatUsername");
// 设置自定义推送提示
JSONObject extObject = new JSONObject();
try {
extObject.put("em_push_title", "custom push title");
extObject.put("em_push_content", "custom push content");
} catch (JSONException e) {
e.printStackTrace();
}
// 将推送扩展设置到消息中
message.setAttribute("em_apns_ext", extObject);
// 设置消息体
message.addBody(txtBody);
// 设置消息回调
message.setMessageStatusCallback(new CallBack() {...});
// 发送消息
ChatClient.getInstance().chatManager().sendMessage(message);
参数 | 描述 |
---|---|
toChatUsername |
消息接收方的用户 ID。 |
em_apns_ext |
消息扩展字段。该字段名固定,不可修改。 |
em_push_title |
自定义推送消息标题。该字段名固定,不可修改。 |
em_push_content |
自定义推送消息内容。该字段名固定,不可修改。 |
设置强制推送后,用户发送消息时会忽略接收方的免打扰设置,不论是否处于免打扰时间段都会正常向接收方推送消息。
// 本示例以文本消息为例,图片和文件等消息类型的设置方法相同。
ChatMessage message = ChatMessage.createSendMessage(ChatMessage.Type.TXT);
TextMessageBody txtBody = new TextMessageBody("test");
// 设置消息接收方:单聊为对端用户的用户 ID;群聊为群组 ID;聊天室聊天为聊天室 ID。
message.setTo("toChatUsername");
// 设置自定义扩展字段。
message.setAttribute("em_force_notification", true);
// 设置消息回调。
message.setMessageStatusCallback(new CallBack() {...});
// 发送消息。
ChatClient.getInstance().chatManager().sendMessage(message);
参数 | 描述 |
---|---|
txtBody |
推送消息内容。 |
toChatUsername |
消息接收方:
|
em_force_notification |
是否为强制推送:
|
发送静默消息指发送方在发送消息时设置不推送消息,即用户离线时,即时通讯 IM 服务不会通过第三方厂商的消息推送服务向该用户的设备推送消息通知。因此,用户不会收到消息推送通知。当用户再次上线时,会收到离线期间的所有消息。
发送静默消息和免打扰模式下均为不推送消息,区别在于发送静默消息为发送方在发送消息时设置,而免打扰模式为接收方设置在指定时间段内不接收推送通知。
// 本示例以文本消息为例,图片和文件等消息类型的设置方法相同。
ChatMessage message = ChatMessage.createSendMessage(ChatMessage.Type.TXT);
TextMessageBody txtBody = new TextMessageBody("test");
// 设置消息接收方:单聊为对端用户的用户 ID;群聊为群组 ID;聊天室聊天为聊天室 ID。
message.setTo("toChatUsername");
// 设置自定义扩展字段。
message.setAttribute("em_ignore_notification", true);
// 设置消息回调。
message.setMessageStatusCallback(new CallBack() {...});
// 发送消息。
ChatClient.getInstance().chatManager().sendMessage(message);
参数 | 描述 |
---|---|
txtBody |
推送消息内容。 |
toChatUsername |
消息接收方:
|
em_ignore_notification |
是否发送静默消息:
|