Android第三方推送服务的选择

2016-8-9更新:这篇《Android端外推送到底有多烦?》作者总结的更全面,建议参考.

由于不可描述原因,谷歌的GCM在国内Android生态中不能普及,导致开发者绞尽脑汁来实现推送到达用户的方法,由于国内ROM厂商越来越多的标配了自启管理等保障用户电量的功能(:-),单独的常住推送service已经完全不能work,于是这期间诞生了守护进程,杀不死进程,全家桶互拉等充分体现国人智慧的产品让人充满了敬佩。作为一个努力想要完成KPI的开发者来说,能不能稍微优雅的而不那么流氓的保障App被杀死后的推送到达率呢,方法就是尽量使用ROM的系统级推送服务。

作为国内机型的两座大山,华为和小米都有自己的面向开发者的推送平台,都是系统级推送(华为文档中虽然没有体现,但经测试是系统级推送),本文就来考察下这两个推送平台。

华为推送

首先需要去华为开发者联盟申请账号,然后开通推送权益。
华为推送支持消息栏消息透传消息

集成

下载SDK包,按照里面的文档在你项目的AndroidManifest.xml添加权限及配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!-- 华为Push权限 --> 
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<!-- ********************************************************************* -->
<!-- ****************** 华为Push(没有引入富媒体相关入口) ****************** -->
<!-- ********************************************************************* -->
<receiver
android:name="com.huawei.android.pushagent.PushEventReceiver"
android:process=":push">
<intent-filter>
<action android:name="com.huawei.android.push.intent.REFRESH_PUSH_CHANNEL" />
<action android:name="com.huawei.intent.action.PUSH" />
<action android:name="com.huawei.intent.action.PUSH_ON" />
<action android:name="com.huawei.android.push.PLUGIN" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />

<data android:scheme="package" />
</intent-filter>
</receiver>
<receiver
android:name="com.huawei.android.pushagent.PushBootReceiver"
android:process=":push">
<intent-filter>
<action android:name="com.huawei.android.push.intent.REGISTER" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
<meta-data
android:name="CS_cloud_version"
android:value="\u0032\u0037\u0030\u0035" />
</receiver>

<!-- PushSDK:Push服务 -->
<service
android:name="com.huawei.android.pushagent.PushService"
android:process=":push" />

说明: 由于并没有使用富媒体推送,所以做了些精简。

继承com.huawei.android.pushagent.api.PushEventReceiver实现自己的receiver并添加到AndroidManifest.xml:

1
2
3
4
5
6
7
8
9
10
<!-- 自定义receiver for huawei push -->
<receiver android:name="com.bytecho.push.HuaweiPushReceiver">
<intent-filter>
<action android:name="com.huawei.android.push.intent.REGISTRATION" />
<action android:name="com.huawei.android.push.intent.RECEIVE" />
</intent-filter>
<meta-data
android:name="CS_cloud_ablitity"
android:value="successRateAnalytics" />
</receiver>

主要功能是接收注册的token和接收透传消息。

测试

华为推送文档十分”简洁”,不支持alias别名,自己后台网页上支持的向所有设备做透传消息,Server SDK竟然不支持(API只支持同时向1000台设备发透传消息),也就是说每次运营人员都要去开发者后台发推送,简直无语。。

华为推送在EMUI系统上应该是系统级服务(adb shell可以发现有com.huawei.android.pushagent.PushService的进程)。

测试结果:

场景 EMUI3.0(Android 4.4.2) EMUI3.1(Android 5.0.2) EMUI4.0(Android 6.0)
App返回键退出 Y Y Y
直接杀APP N Y N
重启 N N N

不知道是不是我实现的有问题,可以看到多数情况这个所谓的’系统级’推送服务根本拉不起你的应用,也就是没有通知收到(应该是收到了,但是没有弹出)。

小米推送

小米推送同样支持支持消息栏提醒透传消息,在MIUI上是系统级服务,共享长连接。

在 MIUI 中,对于小米推送服务的通知栏提醒类消息,通知由系统级应用“小米服务框架”弹出,不需要应用已经被启动运行,因此不会受自启动管理的影响。但是如果在发送消息的时候对应的应用没有被启动,透传类消息是收不到的。

集成

添加配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<!-- 小米Push -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.VIBRATE" />

<permission
android:name="${applicationId}.permission.MIPUSH_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="${applicationId}.permission.MIPUSH_RECEIVE" />


<!-- ********************************************************************* -->
<!-- ***************************** 小米Push ******************************* -->
<!-- ********************************************************************* -->
<service
android:name="com.xiaomi.push.service.XMPushService"
android:enabled="true"
android:process=":push" />
<service
android:name="com.xiaomi.mipush.sdk.PushMessageHandler"
android:enabled="true"
android:exported="true" />
<service
android:name="com.xiaomi.mipush.sdk.MessageHandleService"
android:enabled="true" />
<!--注:此service必须在2.2.5版本以后(包括2.2.5版本)加入-->
<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=":push">
<intent-filter>
<action android:name="com.xiaomi.push.PING_TIMER" />
</intent-filter>
</receiver>

为了接收消息,您需要自定义一个继承自PushMessageReceiver类的BroadcastReceiver,实现其中的onReceivePassThroughMessage,onNotificationMessageClicked,onNotificationMessageArrived,onCommandResult和onReceiveRegisterResult方法,然后把该receiver注册到AndroidManifest.xml文件中。onReceivePassThroughMessage用来接收服务器发送的透传消息,onNotificationMessageClicked用来接收服务器发来的通知栏消息(用户点击通知栏时触发)。

测试

经测试,在MIUI系统上,基本都能保证消息的到达率。

方案

通过以上测试,基本可以放弃在EMUI上单独启用华为推送,目前我们采用的方案比较简单,在MIUI上,采用小米推送,其他机型使用友盟推送。

参考

  1. Android推送平台调研报告
  2. Android Push方案调研
  3. Android 第三方 Push 推送方案使用调查
  4. android整合小米、个推、jpush推送