大家做过安卓推送服务的都知道,如果安卓设备想要收到推送,就要与服务器建立一个长连接通道(莫非你想轮询??)。一旦app被杀掉,维持长连接通道的pushservice服务也会被干掉,所以设备就处于离线状态,也就收不到任何推送。
说到安卓,不得不提苹果,为什么苹果推送没有这个烦恼呢?原因是苹果推送走的是系统推送,由系统去维持长连接通道,所以app杀掉也能收到推送。由于国内能买到的手机都没安装谷歌服务框架,所以造成了如今国内手机无论使用哪种第三方平台推送服务,都无法实现百分百的安卓设备离线(杀掉app)收到推送。
既然国内手机没有使用谷歌原生系统,那我们可以通过国内手机厂商定制系统提供的推送服务,来实现跟苹果一样的系统级别推送。蛋疼的是,国内那么多定制系统,我们要一个一个的做接入。到目前为止,小米、华为和魅族提供了推送服务,而vivo和oppo还没有看到,特别是接入了小米和华为后,我们已经能把推送到达率提高很多很多了。
我们项目组使用了友盟推送,为了提高安卓设备送达率,我们打算接入系统推送通道。我跟着官方文档,参考官方Demo,一步一步做集成。在此过程中发现一些容易踩的坑,希望这篇文章能帮助到你们,快速接入系统推送通道。另外,官方Demo把推送、分享、统计等等功能都集于一身,但缺少了系统推送通道集成的必要代码,所以本文最后有完整的PushDemo项目代码供大家参考。
建议先过一遍官方文档,本教程只对关键要点和注意事项进行说明。请先实现正常的友盟推送流程,本教程是基于正常推送流程之上做集成。建议友盟推送SDK使用最新版本,提高推送稳定性的同时也解决各种水土不服。
本教程的APP包名为com.soecode.lyf.pushdemo
先到对应平台注册帐号,提交资料认证个人开发者。我上次三家同时申请,华为和魅族最快只要一天,小米花了三天时间。
创建应用,包名一定要填写正确,如果遇到包名被占用,请根据提示找回应用。
获取三大平台参数,配到友盟后台,这里没有什么难度。
注意:魅族开放平台包含了flyme推送平台和集成推送平台,前者才是我们想要的,不要搞混了,这是第一个坑。
//小米Push通道
compile 'com.umeng.sdk:push-xiaomi:1.0.0'
//华为Push通道
compile 'com.umeng.sdk:push-huawei:1.0.0'
//魅族Push通道
compile 'com.umeng.sdk:push-meizu:1.0.0'
在Application
类的onCreate
方法添加注册代码
小米和魅族的参数是刚才申请到的应用参数,华为不需要。
//小米通道
MiPushRegistar.register(this, XIAOMI_ID, XIAOMI_KEY);
//华为通道
HuaWeiRegister.register(this);
//魅族通道
MeizuRegister.register(this, MEIZU_APPID, MEIZU_APPKEY);
创建一个Activity,继承于UmengNotifyClickActivity
官方文档这里叫”使用通道弹窗功能”,刚开始看这个小标题没看懂,它其实就是实现点击通知栏跳转到指定Activity的效果。如果没有,点击通知栏会默认启动app,不能跳到指定页面。
虽然这里是叫MipushTestActivity,但三个通道只要创建这一个activity即可。
public class MipushTestActivity extends UmengNotifyClickActivity {
private static String TAG = MipushTestActivity.class.getName();
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_mipush); //这里设置不同的页面,为了区分是友盟推送进来的,还是通道推送进来的
}
@Override
public void onMessage(Intent intent) {
super.onMessage(intent); //此方法必须调用,否则无法统计打开数
String body = intent.getStringExtra(AgooConstants.MESSAGE_BODY);
Log.i(TAG, body);
}
}
在manifest
中配置该Activity
<activity
android:name=".MipushTestActivity"
android:exported="true"
android:launchMode="singleTask" />
魅族需要多配置一个Receiver,继承于UmengMeizuPushReceiver
public class MeizuTestReceiver extends UmengMeizuPushReceiver {
}
在manifest
中配置该Receiver
特别提醒:这里的receiver标签要包在application标签里面,否则魅族通道无法注册成功,第二个坑。
<receiver android:name=".MeizuTestReceiver">
<intent-filter>
<action android:name="com.meizu.flyme.push.intent.MESSAGE" />
<action android:name="com.meizu.flyme.push.intent.REGISTER.FEEDBACK" />
<action android:name="com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK" />
<action android:name="com.meizu.c2dm.intent.REGISTRATION" />
<action android:name="com.meizu.c2dm.intent.RECEIVE" />
<category android:name="${applicationId}">category>
intent-filter>
receiver>
检查app是否已注册到系统通道
调试设备,看logcat日志,在搜索框填入以下命令device token|MiPushBroadcastReceiver|HuaWeiReceiver|MeizuPushReceiver
,勾选Regex
,筛选出关键的打印信息。
如果没有注册成功,根据控制台输出提示排查,并确保参数是否填对。
检查设备是否断开友盟推送长连接
这个可以在【友盟推送后台-工具-Device查询】中查到。
在友盟管理后台发消息
新建消息,勾选MIUI、EMUI、Flyme系统设备离线转为系统下发,页面填写点击通知栏要打开的activity完整包路径(此activity必须继承UmengMeizuPushReceiver),我们这里填刚才新建的类com.soecode.lyf.pushdemo.MipushTestActivity
。
经测试,如果填一个不存在的activity,消息依然会下发成功,但点通知栏会默认打开app启动页。
观察设备是否收到系统通道推送
有两种途径:第一种是看logcat输出,第二种是点通知栏看跳转的页面(如果是系统下发会跳到MipushTestActivity绑定的mipush页面)。
如果收不到,用regid、token或pushId到对应系统平台排查问题。
新增两个字段,如果没用到服务端API请忽略。
"mipush":true
"mi_activity":"com.soecode.lyf.pushdemo.MipushTestActivity"
小米
华为
魅族
友盟论坛上有很多关于推送教程的帖子,但下面这两篇更值得阅读
安卓设备状态离线现象剖析
谈谈消息推送服务的”送达率”
各大平台推送后台入口
我把完整的推送Demo放到github上,比官方Demo更加清晰,欢迎参考。
下载PushDemo