安卓推送一体解决方案
一、背景
作为 IM 的基础能力之一,推送的重要性不言而喻,它是手机操作系统提供给应用触达用户的重要手段之一。苹果系统有 APNS,谷歌也为安卓系统提供了系统级别的推送服务 FCM。
然而,由于 FCM 在我国无法使用。应用为了保证用户能收到重要消息,提高自身的拉活率,早期的时候很多应用都是自建推送通道,通过各种保活措施或者频繁拉活来确保通道存活,这就导致了手机系统内很多服务无法回收,耗电和发热问题突显,成为安卓手机的一大诟病。
为了提升自己的用户感知,谷歌及国内各手机厂商对应用权限的管控越来越严,没有用户的许可,自建通道基本不可能存活。但用户对推送服务的需求又是确实存在的,为了满足这个需求,各手机厂商纷纷推出了自己的系统级别推送服务。
二、现状
目前国内有系统级别推送的主要厂商如下:华为、小米、OPPO、vivo、魅族。
由于各厂商的推送策略和集成方式各不相同,开发者需要研究各家文档,逐个适配,开发门槛高且琐碎。如果有出海需求的应用,还需要对 FCM 单独适配,最多的情况下一个应用可能需要适配多达六个推送通道,开发成本极高。
三、融云解决方案
针对以上问题,融云 SDK 对接了各厂商推送,配合搭建的自有推送通道,智能选择最优方案,最大程度保障了推送到达率。
另外 SDK 还对各厂商推送接口进行了提炼和合并,开发者只需要几行代码即可实现全通道推送能力,极大降低了开发成本。通过提炼后的统一接口,开发者可以很方便的进行通知自定义和事件监控。
融云推送方案
根据客户端和服务端的交互过程,从以下三点对融云推送方案进行说明:
1. 协商通道过程
2. 通道选择策略
3. 接受推送过程
协商通道过程
客户端初始化时,根据本地保存的配置状态决定是否需要和推送服务交互。
若没有完成配置,客户端首先和推送服务建立长连接,并和服务协商需要使用的推送类型,然后根据服务返回的类型调用对应的第三方注册接口,并将获取到的 token 发给服务,至此,协商完毕,断开长连接通道。
若配置已经完成,则直接向第三方推送服务进行注册,获取到第三方推送服务返回的 token 后和本地缓存进行比对,如果不一致,才将新 token 发给融云推送服务,否则不进行任何处理,以免资源浪费。
补充说明一点,协商后如果确认使用融云自建通道,SDK 会在单独的推送进程再次和服务建立长连接,并保持后台存活。
通道选择策略
a. 优先使用系统级通道。客户端首次初始化时,将应用所支持的推送类型和当前设备信息发送给服务端,IM 推送服务结合两者信息以及后台配置信息逐个匹配,优先返回和设备匹配的系统级推送通道。
b. 海外用户优先使用 FCM。鉴于谷歌原生推送(FCM)的固有优势,针对海外用户,融云进行了特殊处理。当用户出访 IP 为海外地址时,优先使用 FCM 通道。
c. 自建通道作为保底手段。如果没有匹配的系统级别推送时,融云会启用自建推送通道 RongPush, 以最大程度保障推送到达率。
接受推送过程
融云推送服务接收到一条消息后,若目标用户离线,则根据协商过程中所使用的推送类型,将消息推送给对应的第三方,第三方推送服务通过自己的系统级推送通道,将消息送达到目标用户设备,并在通知栏展示。
客户端使用说明
1. 配置示例
PushConfig pushConfig = new PushConfig
.Builder()
.enableFCM(true) //配置 FCM 推送
.enableHWPush(true) //配置华为推送
.enableMiPush(MI_APPID, MI_APPKEY) //配置小米推送
.enableMeiZuPush(MEIZU_APPID, MEIZU_APPKEY) //配置魅族推送
.enableVivoPush(true) //配置 vivo 推送
.enableOppoPush(OPPO_APPKEY, OPPO_SECRET) //配置 OPPO 推送
.build();
RongPushClient.setPushConfig(pushConfig); //配置推送
导入第三方推送 jar 后,参考文档在 AndroidManifest.xml 里添加对应声明,再参考上图进行配置,即可为应用实现全通道推送能力。
2. 事件监听
通过继承 SDK 的 PushMessageReceiver 类,即可对推送通知的到达、点击及异常状态进行监听,SDK 已经将通知的相关信息抽象为 PushNotificationMessage 对象,可通过该对象获取业务数据并进行自定义处理,如下图所示:
public class MyNotificationReceiver extends PushMessageReceiver { //推送通知到达事件 @Override public boolean onNotificationMessageArrived(Context context, PushType pushType, PushNotificationMessage message) { return false; } //推送通知点击事件 @Override public boolean onNotificationMessageClicked(Context context, PushType pushType, PushNotificationMessage message) { return false; } //推送配置状态回调 @Override public void onThirdPartyPushState(PushType pushType, String action, long resultCode) { super.onThirdPartyPushState(pushType, action, resultCode); } }
3.各平台支持能力概览
推送通道 | 推送 方式 | 通知到达 是否回调 | 通知到达 可否自定义 | 通知点击 是否回调 | 通知点击 是否支持 自定义点击跳转 |
华为 | 通知 | 否 | 否 | 否 | 是 (融云开发者后台配置点击动作) |
小米 | 通知 | 是 | 否 | 是 | 是 |
OPPO | 通知 | 否 | 否 | 否 | 否 |
vivo | 通知 | 否 | 否 | 是 | 是 |
魅族 | 通知 | 是 | 否 | 是 | 是 |
FCM | 透传 | 是 | 是 | 是 | 是 |
RongPush | 透传 | 是 | 是 | 是 | 是 |
上表中,推送方式分为通知方式和透传方式,两者区别如下:
通知方式,是指由手机系统直接在通知栏弹出通知,不触发应用,到达率高且节电。
透传方式,指服务将消息原始数据下发到客户端,客户端通过广播接收器接受数据再进行处理。需要拉起应用,一般依赖于客户是否打开自启动权限,到达率低。