Android

实现离线推送

更新时间: 2024/03/14 16:36:28

为了提高消息送达率,云信引入手机系统厂商推送。手机系统级别的厂商推送(如小米、华为、vivo、OPPO、魅族等)的优势在于其拥有稳定的系统级长连接,可以做到随时接收推送。

功能概述

NIM SDK 支持离线推送消息功能。

当用户清理掉应用进程(被冻结、主动关闭)、网络不稳定等导致客户端 SDK 无法与云信服务器保持正常连接时,将使用手机厂商系统级推送来告知用户有消息需要接收。

您可以通过集成各手机厂商推送 SDK,与 NIM SDK 搭配使用,实现离线推送功能。

技术原理

云信 IM 实现离线推送的技术原理如下:

前提条件

在实现离线推送功能之前,请确保:

  • 开发环境满足如下要求:

    • Android 4.4 及以上版本。
    • 自 v6.9.0 起,改用 AndroidX 支持库,Target API 改为 28,不再支持 support 库。
  • 集成 SDK

  • 已在云信控制台创建应用,获取 App Key。

  • 注册云信 IM 账号,获取 accid 和 token。

实现流程

步骤 1:集成第三方厂商离线推送服务

请参考具体厂商的推送集成文档,集成需要使用到的第三方厂商离线推送 SDK,接入各厂商的离线推送服务。

目前支持以下第三方推送厂商:

第三方推送厂商 当前兼容版本 集成指南
小米 IM 开发版:5.6.2
IM 稳定版:5.6.2
集成小米推送
华为 IM 开发版:6.9.0.300
IM 稳定版:6.9.0.300
集成华为推送
荣耀 IM 开发版:7.0.41.301
IM 稳定版:7.0.41.301
集成荣耀推送
OPPO IM 开发版:3.1.0
IM 稳定版:3.1.0
集成 OPPO 推送
vivo IM 开发版:3.0.0.4_484
IM 稳定版:3.0.0.4_484
集成 vivo 推送
魅族 IM 开发版:4.2.3
IM 稳定版:4.2.3
集成魅族推送
谷歌 FCM IM 开发版&稳定版:firebase-bom:28.4.2
具体版本:firebase-messaging:23.0.0firebase-analytics: 20.0.0
集成谷歌推送

步骤 2:集成 NIM SDK

集成 NIM SDK 时,需要添加第三方厂商推送辅助包。

  • 若自动集成,则需要在 dependencies 中添加相关依赖。

    dependencies {
        compile fileTree(dir: 'libs', include: '*.jar')
        // 添加依赖。注意,版本号必须一致。
    
        // 基础功能 (必需)
        implementation "com.netease.nimlib:basesdk:${LATEST_VERSION}"
        // 通过云信来集成第三方厂商推送需要
        implementation "com.netease.nimlib:push:${LATEST_VERSION}"
    }
    
  • 若手动集成需要将下载的 nim-push-x.x.x.jar 文件拷贝到您的项目路径的 app/libs 目录下;然后在该 .jar 文件上右键添加为依赖。

步骤 3:初始化 NIM SDK

初始化 NIM SDK 时,完成厂商的推送证书配置,并选择推送渠道。

  1. 需要将推送证书的信息配置到初始化参数 SDKOptions.mixPushConfig 中。

    小米
    MixPushConfig config = new MixPushConfig();
    // 传入从小米推送平台获取到的AppId与AppKey
    config.xmAppId = "xxxx";
    config.xmAppKey = "xxxx";
    // 传入云信控制台上小米推送对应的证书名
    config.xmCertificateName = "xxxx";
    ...
    options.mixPushConfig = config;
    
    华为
    MixPushConfig config = new MixPushConfig();
    // 传入华为推送的APP ID
    config.hwAppId = "xxxx";
    // 传入云信控制台上华为推送证书名
    config.hwCertificateName = "xxxx";
    ...
    options.mixPushConfig = config;
    
    荣耀
    MixPushConfig config = new MixPushConfig();
    // 传入荣耀推送证书名,荣耀推送的 appId请在 AndroidManifest.xml 文件中配置
    config.honorCertificateName = "xxxx";
    ...
    options.mixPushConfig = config;
    
    vivo
    MixPushConfig config = new MixPushConfig();
    // 传入云信控制台上配置的vivo推送证书名,vivo 推送的 appId appKey请在 AndroidManifest.xml 文件中配置
    config.vivoCertificateName = "xxxx"; 
    ...
    options.mixPushConfig = config;
    
    OPPO
    MixPushConfig config = new MixPushConfig();
    
    config.oppoAppId = "xxxx";
    config.oppoAppKey = "xxxxxx";
    // 注意区分AppSercet与MasterSecret
    config.oppoAppSercet = "xxxxxxx";
    // 传入云信控制台上配置的oppo推送证书名
    config.oppoCertificateName = "xxxx";
    ...
    options.mixPushConfig = config;
    
    魅族
    MixPushConfig config = new MixPushConfig();
    
    config.mzAppId = "xxx";
    config.mzAppKey = "xxxx";
    config.mzCertificateName = "xxxx";
    ...
    options.mixPushConfig = config;
    
    谷歌
    //传入云信控制台上配置的谷歌推送证书名,谷歌推送的  AppSecret 请在 AndroidManifest.xml 文件中配置
    MixPushConfig config = new MixPushConfig();
    
    config.fcmCertificateName = "xxxx";
    ...
    options.mixPushConfig = config;
    

    推送证书名长度不超过 32 个字符,否则登录时会报错 500。

  2. 选择推送渠道。

    • 如果SDKOptions.mixPushConfig.autoSelectPushType为 false(默认),则 SDK 直接选择服务端推荐的推送渠道。

    • 如果配置SDKOptions.mixPushConfig.autoSelectPushType为 true,则 SDK 根据实际的 token 的获取情况确定推送渠道,此时服务端推荐的推送渠道为最高优先级。需要确定推送渠道时,先进行本地支持性判断,然后将向所有可能支持的推送厂商申请 token,并在成功拿到的 token 中选择优先级更高的渠道。

    SDK 默认 Google FCM 推送的优先级最低,即如果同时接入了 FCM 和其他厂商推送,则会优先走其他厂商推送通道。但是如果您的应用用户主要分布在海外,在云信控制台已设置 FCM 推送优先控制台:应用详情 > 更多 > 证书管理),那么同时接入 FCM 和其他厂商推送 SDK 的场景下,优先走 FCM 推送通道。

  3. Application#onCreate 中启用华为、荣耀、OPPO 厂商的推送服务,即对华为、荣耀、OPPO 推送服务进行初始化。其他厂商推送服务无需额外初始化,可忽略该步骤。

    华为
    public class NimApplication extends Application {
        ...
        @Override
        public void onCreate() {
            ...
            if (NIMUtil.isMainProcess(this)) {
                ...
                // 在此处添加以下代码
                com.huawei.hms.support.common.ActivityMgr.INST.init(this);
                ...
            }
        }
    }
    
    荣耀
    public class NimApplication extends Application {
        ...
        @Override
        public void onCreate() {
            ...
            if (NIMUtil.isMainProcess(this)) {
                ...
                // 在此处添加以下代码
                HonorPushClient.getInstance().init(getApplicationContext(), true);
                ...
            }
        }
    }
    
    OPPO
    public class NimApplication extends Application {
        ...
        @Override
        public void onCreate() {
            ...
            if (NIMUtil.isMainProcess(this)) {
                ...
                // 在此处添加以下代码
                com.heytap.msp.push.HeytapPushManager.init(this, true);
                ...
            }
        }
    }
    

    若您正确集成第三方推送(已传相关推送 token 至云信服务器),SDK 日志会打印以下相应记录。其中pushTypetype表示推送类型(5 小米、6 华为、7 魅族、8 谷歌FCM、9 vivo、10 OPPO、0 不支持),tokenName表示推送证书名称,token表示推送 token。

    [ui]mix_push: after login, mix push state=MixPushState{pushType=5, hasPushed=0, lastDeviceId=''}
    [ui]mix_push: commit mix push token:type 5 tokenName PUSH_CER_NAME token y7ssE..................sLxnU
    
  4. (可选)初始化之后,无论是否登录,您都可以调用 MixPushServiceregisterPush 方法获取推送 Token。(Token 会通过 MixPushServiceObserveobserveMixPushToken 回调得到。)

    如果您的应用用户主要分布在海外,需要优先走 FCM 推送通道,需要提前在云信控制台已设置 FCM 推送优先控制台:应用详情 > 更多 > 证书管理),那么调用该接口时,会优先获取 FCM 推送的 Token。

步骤 4:测试离线推送

消息发送方:

发送消息或自定义系统通知给接收方(离线),具体的收发流程可参见消息收发自定义系统通知收发

这里以发送文本消息为例,通过调用 sendMessage 实现。发送的消息默认需要推送,如需设置推送文案,推送角标,推送文案前缀等,请参见配置消息的推送属性

// 该帐号为示例
String account = "testAccount";
// 以单聊类型为例
SessionTypeEnum sessionType = SessionTypeEnum.P2P;
String text = "this is an example";
// 创建一个文本消息
IMMessage textMessage = MessageBuilder.createTextMessage(account, sessionType, text);
// 发送给对方
NIMClient.getService(MsgService.class).sendMessage(textMessage, false).setCallback(new RequestCallback<Void>() {
                @Override
                public void onSuccess(Void param) {

                }

                @Override
                public void onFailed(int code) {
                    
                }

                @Override
                public void onException(Throwable exception) {

                }
            });

消息接收方:

接收方将会在登录后接收到离线推送。

(可选)步骤 5:关闭/开启离线推送服务

NIM SDK 的第三方推送服务功能默认开启,无需单独调用开启服务接口。若后续不想使用第三方推送服务,可调用 enable 方法进行关闭。

NIMClient.getService(MixPushService.class).enable(false).setCallback(...)

推送相关文档

常见问题

触发离线推送的条件

Q:触发离线推送的条件是什么?

A:Android 切换到后台并且等 app 被系统回收时,或者用户主动关闭 app,才能触发推送条件。因此,若要测试 Android 推送问题,请登录后关闭 app,确保满足推送条件。

不会触发推送的场景

Q:哪些场景下不会触发推送?

A: IM 账号未登录/已登出/被踢出,不会触发推送。App 在前台,也不会触发推送。用户登录 IM 账号,并且未主动登出或者没有被踢出,可能触发推送。

此文档是否对你有帮助?
有帮助
去反馈
  • 功能概述
  • 技术原理
  • 前提条件
  • 实现流程
  • 步骤 1:集成第三方厂商离线推送服务
  • 步骤 2:集成 NIM SDK
  • 步骤 3:初始化 NIM SDK
  • 步骤 4:测试离线推送
  • (可选)步骤 5:关闭/开启离线推送服务
  • 推送相关文档
  • 常见问题
  • 触发离线推送的条件
  • 不会触发推送的场景