Android 混合推送指南
混合推送概述
自 Android 8.0 之后,系统权限控制越来越严,第三方推送通道的生命周期受到较大限制;同时,国内主流厂商也开始推出自己独立的推送服务,而厂商间千差万别的繁杂接口徒增了开发和代码维护的难度。为此,我们推出混合推送方案。我们逐一对接国内主流厂商,将它们不同的接口隐藏起来,让开发者通过统一的 API 完成推送任务。这保障了主流 Android 系统上的推送到达率,也大幅降低了开发复杂度。
在混合推送方案里,消息下发时使用的通道不再是我们自己维持的 WebSocket 长连接,而是借用厂商和 OS 层的系统通道进行通信。 一条推送消息下发的步骤如下:
- 开发者调用云服务 Push API 请求对全部或特定设备进行推送;
- 云推送服务端将请求转发给厂商的推送接口;
- 厂商通过手机端的系统通道下发推送消息,同时手机端系统消息接收器将推送消息展示到通知栏;
- 终端用户点击消息之后唤起目标应用或者页面。
整个流程与苹果的 APNs 推送类似,SDK 在客户端基本不会得到调用(具体依赖于厂商的实现方案),消息的下发和展示都依赖厂商客户端的行为。所以如果部分厂商在某些推送中夹带了其他非开发者提交的消息,或者在服务启用的时候,有额外营销性质的弹窗,这都是厂商自己的行为,与我们完全无关,还请大家了解。另外,如果开发者碰到厂商 SDK 的问题,我们也无法深入调查,还请大家自行到厂商的论坛或技术支持渠道咨询解决。
Android 混合推送功能仅对商用版应用开放,如果希望使用该功能,请进入 开发者中心 > 你的游戏 > 游戏服务 > 云服务 > 推送通知 > 设置 > 混合推送,打开混合推送的开关。
注意,混合推送可以随时按需开关。当该选项关闭后,下一次 Android 推送会与普通推送一样自动选择自有通道送达客户端,除了会再次遇到上面提到的自有通道在部分 ROM 上会受到限制的问题之外,不会有别的影响。而当该选项再次开启后,Android 推送又会去选择厂商推送渠道。
开启了混合推送之后,Installation 表中每一个设备对应的记录,会增加 registrationId
字段,用于记录厂商分配的注册 id(类似于 APNs 的 device token),同时还会增加一个 vendor
字段(如果没有这一字段,则说明客户端集成有问题),其值为
vendor | 厂商 |
---|---|
HMS | 华为 HMS 推送 |
mi | 小米推送 |
mz | 魅族推送 |
oppo | OPPO 推送 |
vivo | vivo 推送 |
honor | 荣耀推送 |
注意,混合推送对接的是厂商各自的推送服务,需要单独配置,不支持混用。 通常情况下,需要提交不同的版本(分别对接厂商的推送服务)到相应厂商的应用商店。 如果希望使用统一版本,那么需要自行判断手机型号,在手机上开启对应的推送。
推送提醒的红点或角标展示
很多开发者都希望可以在应用桌面开启角标或者小红点,以达到更好的提醒效果。国内厂商对此功能的开放程度不一,详见下表:
厂商 | 是否支持角标/红点 | 是否需要配置 | 适配说明 |
---|---|---|---|
华为 | 支持角标 | 是 | 请参考下文华为角标适配说明 |
小米 | 支持角标 | 否 | 遵从系统默认逻辑,感应通知栏通知数目,按 1 自动增减 |
OPPO | 支持红点 | 否 | 圆点展示需由用户在通知设置中手动开启,遵从系统默认逻辑,有通知则展示,无则不展示;数值展示只对指定应用开启,例如 QQ、微信,需向官方进行权限申请,暂无明确适配说明。 |
vivo | 支持角标 | 是 | 参考下文vivo 手机角标适配说明 |
魅族 | 支持红点 | 否 | 遵从系统默认逻辑,仅支持红点展示,有通知则展示,无则不展示 |
荣耀 | 支持角标 | 否 | 客户端无需配置,服务端推送时通过 badge 参数进行设置,详情可参考:荣耀服务端推送. |
通知栏消息与透传消息
很多开发者会关心通知栏消息和透传消息是否支持,因为应用状态不同,可能接收到消息的途径不一样,产品层面希望的处理方式也有差异。不同厂商对透传消息的支持不一样,详见下表:
厂商 | 是否支持透传消息 |
---|---|
华为 | 是 |
小米 | 是 |
OPPO | 否 |
vivo | 否(老版本有透传接口,新版本已不建议使用) |
魅族 | 否 |
荣耀 | 是 |
注意,如果指定了 silent
为真,但厂商不支持透传,那么这条消息会被丢弃,推送记录中会记录相应的报错信息。
即时通讯的离线推送
在即时通讯服务中,在 iOS 平台上如果用户下线,是可以启动离线消息推送机制的,对于 Android 用户来说,如果只是使用云推送自有通道,那么是不存在离线推送的,因为聊天和推送共享同一条 WebSocket 长链接,在即时通讯服务中用户下线了的话,那么推送也必然是不可达的。但是如果启用了混合推送,因为推送消息走的是厂商通道,这一 点和 iOS 基本一致,所以这时候 Android 用户就存在离线推送的通知路径了。 也就是说,如果开启了混合推送,那么即时通讯里面的离线推送和静音机制,对使用了混合推送的 Android 用户也是有效的。
受限说明
推送消息长度限制:
- 消息中的应用包名最大支持 128 字节,消息内容最大支持 4KB 字节。
最低 Android 版本要求:
- 华为推送需要用户手机上安装 HMS Core(APK)6.11.0.300 及以上版本,最低 Android 版本为 4.4(minSdkVersion 19)。
- 小米推送服务 SDK 支持的最低安卓版本为 4.4(minSdkVersion:19)。
- vivo 推送服务支持的最低 Android 版本为 6.0(minSdkVersion:23)。
- OPPO 推送只支持 Android 4.4 或以上版本的手机系统(minSdkVersion:19)。
- 魅族(flyme)推送只支持 Android 4.2 或以上版本的手机系统(minSdkVersion:17)。
- 荣耀 推送支持国内Magic UI 4.0及以上,海外Magic UI 4.2及以上(minSdkVersion 19)。
影响送达率的因素说明:
- 终端设备是否在线。如果设备离线,推送服务会缓存消息,待设备上线后,再将消息推送给设备。
- 终端设备上集成推送服务 SDK 的应用是否被卸载。
- 终端设备的网络状况是否稳定。
- 终端设备的安全控制策略。
- 透传消息的送达受 Android 系统和应用是否驻留在后台影响。
下面我们逐一看看如何对接华为、小米、魅族等厂商的推送服务。
推荐的接入方式
混合推送本质上还是依赖于各厂商的 SDK 和服务端能力,我们的客户端 SDK 只是对厂商 SDK 的包装,而实际的推送请求也是通过 LeanCloud 中转之后发送到厂商后台。因为是一对多的关系,我们的客户端 SDK 更新速度可能跟不上厂商的迭代速度,因此建议大家直接对接厂商 SDK,然后在客户端把厂商分配的「注册 id」与厂商标识(见上一章 vendor 的说明)保存到设备信息(Installation
)中,这样之后一样可以通过我们的推送 API 来给所有设备正确发送推送信息。
客户端接入方法
不同厂商获取「注册 id」的流程和接口会有不同,可以参考厂商平台的开发指南,这里我们说一下集成厂商 SDK 获取到「注册 id」之后如何按照规范来保存设备信息。
华为推送(HMS)
开发者从 HmsMessageService
继承自己的实现类,然后在 onNewToken(String token)
回调函数中调用如下代码进行保存:
public static void updateInstallation(String hwToken) {
if (StringUtil.isEmpty(hwToken)) {
return;
}
LCInstallation installation = LCInstallation.getCurrentInstallation();
if (!VENDOR.equals(installation.getString(LCInstallation.VENDOR))) {
installation.put(LCInstallation.VENDOR, "HMS");
}
if (!hwToken.equals(installation.getString(LCInstallation.REGISTRATION_ID))) {
installation.put(LCInstallation.REGISTRATION_ID, hwToken);
}
installation.saveInBackground().subscribe(ObserverBuilder.buildSingleObserver(new SaveCallback() {
@Override
public void done(LCException e) {
if (null != e) {
LOGGER.e("update installation error!", e);
} else {
LOGGER.d("Huawei push registration successful!");
}
}
}));
}
示例代码可以参考LCHMSMessageService。
小米推送
开发者从 PushMessageReceiver
继承自己的实现类,然后在 onReceiveRegisterResult
回调函数中调用如上例代码进行保存(记得将 vendor
换成 mi
)。示例代码可以参考LCMiPushMessageReceiver。
OPPO 推送
开发者从 ICallBackResultService
继承自己的实现类,然后在 onRegister
回调函数中调用如上例代码进行保存(记得将 vendor
换成 oppo
)。示例代码可以参考LCOPPOPushAdapter。
vivo 推送
开发者从 OpenClientPushMessageReceiver
继承自己的实现类,然后在 onReceiveRegId
回调函数中调用如上例代码进行保存(记得将 vendor
换成 vivo
)。示例代码可以参考LCVIVOPushMessageReceiver。
魅族推送
开发者从 MzPushMessageReceiver
继承自己的实现类,然后在 onRegisterStatus
回调函数中调用如上例代码进行保存(记得将 vendor
换成 mz
)。示例代码可以参考LCFlymePushMessageReceiver。
荣耀推送
开发者从 HonorMessageService
继承自己的实现类,然后在 onNewToken
回调函数中调用如上例代码进行保存(记得将 vendor
换成 honor
)。示例代码可以参考LCHonorMessageService。
发送混合推送的服务端 API
可以参考这里的说明来发送推送请求:推送 REST API 使用指南。
如果开发者要集成我们封装的混合推送 SDK,可以继续往下阅读,如果自行接入厂商 SDK,则可以忽略下文。
混合推送 library 的构成
我们提供了一个 all-in-one 的混合推送模块,统一支持华为(HMS)、小米、OPPO、vivo、魅族、荣耀推送,开发者依赖如下:
cn.leancloud:mixpush-android:8.2.24@aar
从 6.5.1 版本开始,我们额外提供了单一厂商的推送 library,以支持不希望全部集成的产品之需求,新 library 与厂商的对应关系如下:
- 华为(HMS)
cn.leancloud:mixpush-hms:8.2.24
- 小米
cn.leancloud:mixpush-xiaomi:8.2.24
- 魅族
cn.leancloud:mixpush-meizu:8.2.24
- OPPO
cn.leancloud:mixpush-oppo:8.2.24
- vivo
cn.leancloud:mixpush-vivo:8.2.24
- 荣耀
cn.leancloud:mixpush-honor:8.2.24
两组 library 的使用方法基本相同,开发者可以根据自己的需要选取合适的 library。有一点需要注意的是,在 6.5.1 及后续版本的 library 中,由于小米、OPPO、vivo 、荣耀并没有将他们的 SDK 包发布到公开源供开发者引用,所以如果是使用这几个厂商的推送,需要开发者将厂商的 SDK 包手动加入工程中。
混合推送 SDK 的获取方法
我们已经把所有的 library 推送到了 maven 中央仓库,开发者可以直接在 build.gradle 中进行引用(maven 依赖方式)。
但是对于华为和荣耀推送(从 8.2.16 版本开始支持),因为厂商是将他们的基础 sdk 发布到私有仓库,所以我们在使用 mixpush-android
(all in one 版本) 或者 mixpush-hms
(华为推送)/mixpush-honor
(荣耀推送)时,需要在项目级 build.gradle 文件的 allprojects/repositories
和 buildscript/repositories
中增加仓库地址(分别对应不同的推送目标):
maven {url 'http://developer.huawei.com/repo/'}
maven {url 'https://developer.hihonor.com/repo/'}
开发者可以参考我们的 all-in-one demo 来进行集中配置。
华为推送-HMS 版本
环境配置
- 注册华为账号:在 华为开发者联盟 注册华为开发者账号。
- 开发前准备:接入华为 PUSH 之前,需要创建应用并配置应用签名,具体可参考华为官方文档:开发准备。
- 打开推送服务开关:登录华为开发者联盟,按照开发准备一文中的提示开通推送服务。
- 将华为 App 信息保存到 开发者中心 控制台:将上面创建的华为 App 信息(主要有 AppId 和 AppSecret),通过 开发者中心 > 你的游戏 > 游戏服务 > 云服务 > 推送通知 > 设置 > 混合推送 与应用关联。
接入 SDK
获取 HMS SDK
当前版本 SDK 依赖华为 PushKit V5 版本,开发者可以参考华为官方文档完成 HMS SDK 的接入。 其主要步骤有:
-
在 AndroidStudio 开发环境中添加当前应用的 AppGallery Connect 配置文件,如下图所示:
-
配置 HMS SDK 的 maven 仓库地址。
-
在项目级 build.gradle 文件的
allprojects/repositories
和buildscript/repositories
中增加仓库地址:maven {url 'http://developer.huawei.com/repo/'}
-
-
在项目级
build.gradle
的buildscript/dependencies
里面增加配置:dependencies {
classpath 'com.android.tools.build:gradle:4.1.1'
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
}