小米推送技术常见问题解答

以下为一些常见的技术问题解答及常见概念的理解,本文档将持续补充,对推送有疑问的开发者同学可以自行 Ctrl+F 搜索关键字找寻解答 

1.小米推送的送达率是怎么计算的?有哪些影响送达率的因素?

答:首先需要说明的是小米推送服务送达率的计算方式,分子比较容易理解,就是本次推送真正送达的设备数。分母则是本次推送请求所覆盖的所有的设备数,如果目标对象的选取是所有用户,那分母就是历史上所有激活过推送服务的有效设备数;如果是按照标签选取的,那分母是历史上所有订阅过这个标签的有效设备数;如果是按照别名或者regID来选取,那么分母就是所请求的所有合法的别名或regID。其中,设备的有效性是通过如下规则来判断的:如果应用调用了unregisterPush,或者在MIUI上卸载了,或者超过3个月都没有和小米服务器建立过长连接,则会判定设备失效。 按照这种计算方式,会有如下几个影响送达率的因素:1.应用的留存率。已经卸载了app的设备,肯定是推送不到的,但按照目前的计算方式,大部分的卸载设备都会被计入分母(计划推送数)当中。2.应用所在设备的联网情况。如果在消息有效期内,设备一直不联网,那消息也是不能送达的,但也会被计入分母当中。3.消息的有效期。有效期越短,在有效期内联网的设备数势必就越少,因此送达率会随之下降。4.目标设备的选取。如果选取的是全量用户,那其送达率肯定会比按照用户联网情况精准提取目标设备(如选取7天内有过打开应用行为的用户)要低。

2. 透传和通知栏,在送达率上有什么分别?

答:首先解释一下透传和通知栏方式的原理,透传是指当小米推送服务客户端SDK接收到消息之后,直接把消息通过回调方法发送给应用,不做任何处理;而通知栏方式,则在设备接收到消息之后,首先由小米推送服务SDK弹出标准安卓通知栏通知,在用户点击通知栏之后,激活应用。 在非MIUI系统中,由于维护小米推送服务长连接的service是寄生在App的运行空间当中的,因此透传和通知栏方式在送达率上并没有任何区别,都需要应用驻留在后台。即,如果一台设备通知栏消息能够接收到并弹出,那么其透传消息也同样能接收到。 在MIUI系统中,由于长连接是由MIUI系统服务建立并维护的,因此在接收消息的时候并不需要应用驻留后台。如果采用通知栏方式接收消息,由于通知栏也是MIUI系统服务弹出的,就可以做到不需要用户后台驻留或者可以自启动消息就能送达。而如果采用透传消息,由于需要直接执行应用的代码,因此即使消息已经到了系统服务,如果应用没有驻留后台或者能自启动,消息依然不能送达,需等下次用户手动点击激活应用后,才能接收到消息。 综上,在MIUI系统中,通知栏消息的送达率会远高于透传方式;在非MIUI系统中,通知栏和透传方式的送达率是一样的。      

3. 我第一次接触安卓版小米推送服务,使用你们的demo没有成功,怎么办?

答:第一次使用小米推送服务(安卓版),请仔细阅读如下指南:/doc/?p=3080。一般注册推送服务没成功,常见的原因如下: 1.没有开启推送服务。使用推送服务前需要登录开发者账号、创建应用、开通推送服务3个步骤,缺一不可。 2.没有正确配置AndroidManifest.xml文件。需要特别注意包名、权限部分,包名需要跟开发者站点上开通推送服务的一致,权限的前缀需要改成包名。 3.系统时间错误。由于小米推送服务需要使用https请求向服务器注册一个匿名账号,在次过程中如果系统时间错误,会引起https过期,导致注册不成功。 4.联网被阻止。小米推送服务客户端需要使用5222和443两个端口,如果在公司内网,需要联系IT部门把这两个端口开放。同时需要检查应用的联网是否会被一些手机安全助手阻止。需要特别注意的是,在MIUI系统上,长连接是由“小米服务框架”这个系统应用维护的,因此需要确保这个应用的联网并没有被阻止。    

4.regID是根据什么生成的?会不会经常变化?

答:regID是在客户端向小米推送服务注册时,小米推送服务端根据设备标识、appID以及当前时间戳生成,因此能够保证每个设备上每个app对应的regID都是不同的。当app注册成功后,小米推送服务客户端SDK会在本地通过shared_prefs来保存这个regID,之后app调用注册,SDK后会在本地直接读取出这个regID并直接返回,不会重新请求服务器。因此只要应用不卸载重装或者清除应用本地数据,regID就不会变化。否则,如果SDK没有从本地读取到缓存的regID,则会向服务端重新请求,此时regID会重新生成。

5. 如果我使用通知栏类型消息,能否在通知栏消息到达之前,先执行一段app的代码?或者在通知栏到达时,通知app?

答:在MIUI系统上,通知栏类型的消息,是不需要应用启动就能弹出的(这一特性决定了通知栏消息的弹出可以不受应用自启动管理的影响),因此在整个弹出通知栏消息的过程中,app是完全不可感知的,当用户点击通知栏消息之后,才会执行到app的代码。

6. 为什么onNotificationMessageArrived方法没被调用到?

答:首先,确定你的接入是否正确,这个方法需要在manifest中添加<action android:name=”com.xiaomi.mipush.MESSAGE_ARRIVED” />这个action。 在接入正确的前提下,这个方法也不是保证一定能被调用的。在MIUI系统上,这个方法的调用需要同时满足如下两个条件:1.新版的MIUI。这个特性是在2015年才加进小米推送服务的,因此需要MIUI升级到较新的版本才能调用这个方法。2.需要应用驻留后台。小米推送服务的通知栏消息,是可以在应用不启动的前提下,就弹出通知栏消息的,在这种情况下, 由于MIUI的自启动管理,限制了应用不能在被杀后被后台唤醒,所以推送消息不能直接唤醒应用执行这个方法。

7. 为什么我在onNotificationMessageClicked方法中的startActivity不能调起目标界面?

答:由于onNotificationMessageClicked中传入的context是application context,本身没有activity栈,因此需要在创建activity时候加入NEW_TASK的flag: Intent i = new Intent(context, MyActivity.class); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i);

8. 当我的应用被杀掉之后,还能否接收到小米推送服务的消息?

答:有如下几种情况:如果是在MIUI系统中,使用通知栏类型的消息,是不需要应用出于启动状态就能接收并弹出通知栏的。使用透传消息,则需要应用驻留后台才能接收,由于MIUI的自启动管理限制,所以如果应用被杀,是收不到透传消息的。而如果是在非MIUI系统中,是需要应用驻留后台才能接收消息的,因此如果应用被杀死并且不能后台自启动的话,是没有办法接收消息的。为了让app尽可能的驻留后台,小米推送服务SDK监听了网络变化等系统事件,并且有应用之间的互相唤醒,但这些措施并不能保证应用可以一直在后台驻留。

9.  regID在哪些情况下会失效?我如何获取失效的regID?

答:regID在如下几种情况下会被判断失效:1.app卸载重装或者清除数据后重新注册,这种情况下会生成一个新的regID,而老的regID会失效。2.app调用了unregisterPush。3.在MIUI上,app卸载时,如果能成功上报,则regID会被判定失效。4.设备超过3个月没有和小米push服务器建立长连接。 可以通过feedback接口从小米推送服务后台拉取失效regID的列表,具体用法请参照服务端SDK文档。

10.  有没有方法检测小米推送是否已经注册的方法

答:客户端调用getregid,如果有返回,就注册成功了

11.  为什么我的设备在调用registerPush的时候会出现no account的错误?

答:在app第一次在一台设备上注册推送服务时,sdk会通过https请求,从小米推送服务器生成一个匿名账号。这个错误是由于这个请求失败导致的。一般请求失败常见的原因包括如下几种:1.系统时间错误。时间错误会导致https在校验证书有效期的时候,出现证书过期,导致https请求失败。2.网络原因。这个大部分的原因都是设备架了代理服务器或连了vpn,如果排除这些原因,就检查一下app是否申请了联网权限,是否被什么安全软件阻止了登录,公司wifi是否能用,等等。3.如果是在MIUI系统上,生成匿名账号是在一个叫小米服务框架的系统app上完成的,还需要检查这个app的联网是不是在安全中心的联网控制中被手动关闭了。

12.  小米push是不是共享通道的?

答:在MIUI系统中,push服务的消息走的是系统通道,不需要应用单独建立连接。在非MIUI上,通道会建立在每个app的进程中,每个接入mipush服务的app都会建立一条单独的通道。这种设计的考虑原因如下:使用共享通道,会有如下几个问题解决不了,1.流量。假如你的app不幸被选中成为其它app的消息通道,而某个恶意app通过这个通道发了大量的消息,所产生的流量,都会算在你的app的头上。2.安全性。如果你的消息走的是别的app的通道,数据需要通过另一个app的进程中转,则在这过程中很容易被伪造、纂改、拦截。 使用共享通道,好处无非就是这2个:1.appA没启动,appB启动了,可以通过appB的通道发消息。2.单通道比多通道省电。而小米推送服务通过1.应用之间互相唤醒。2.时钟周期同步唤醒这两个机制,同样也能做到这两点,并且不需要开发者承担使用单通道的风险。

13.  alias和user account有什么区别?

答:alias和user account都可以用来设置设备对应的用户账号,所不同的是,一个alias只能对应一台设备,如果有多台设备设置了同样的alias,则最后一个设置成功的生效,其它设备就会失效。而一个user account可对应10台以内的设备。因此如果应用是单点登录的,一个账号只会在一台设备上生效,用alias会比较合适。而如果产品需求是单账号多点登录同时接收消息,则用user account会更合适。

14. 自定义的广播继承PushMessageReceiver的,已经在AndroidManifest注册了,但是没有回调到自定义的广播里面。查看log日志,显示xx.xx.xx receive message without registration. need unregister or re-register

答:第一次使用小米推送服务(安卓版),请仔细阅读如下指南:/doc/?p=3080。

一般注册推送服务没成功,常见的原因如下:

1.没有开启推送服务。使用推送服务前需要登录开发者账号、创建应用、开通推送服务3个步骤,缺一不可。
2.没有正确配置AndroidManifest.xml文件。需要特别注意包名、权限部分,包名需要跟开发者站点上开通推送服务的一致,权限的前缀需要改成包名。
3.系统时间错误。由于小米推送服务需要使用https请求向服务器注册一个匿名账号,在次过程中如果系统时间错误,会引起https过期,导致注册不成功。
4.联网被阻止。小米推送服务客户端需要使用5222和443两个端口,如果在公司内网,需要联系IT部门把这两个端口开放。同时需要检查应用的联网是否会被一些手机安全助手阻止。需要特别注意的是,在MIUI系统上,长连接是由“小米服务框架”这个系统应用维护的,因此需要确保这个应用的联网并没有被阻止。

15.  为什么在数据统计后台看,按天统计中,会出现计划推送少于送达数的现象?

答:这是正常现象,在按天统计中,计划推送是指当天的所有请求总共覆盖了多少设备数,而送达数则是当天这个app所有的送达,因此这个送达数不但包括当天发的消息送达了多少,也包括了之前发的消息,作为离线消息当天抵达设备的数量。因此这个送达数是存在大于计划推送数的可能性的。

16. 计划推送数是指什么?怎么计算的?

答:计划推送数是指推送请求所覆盖的所有的设备数,如果目标对象的选取是所有用户,那分母就是历史上所有激活过推送服务的有效设备数;如果是按照标签选取的,那分母是历史上所有订阅过这个标签的有效设备数;如果是按照别名或者regID来选取,那么分母就是所请求的所有合法的别名或regID。其中,设备的有效性是通过如下规则来判断的:如果应用调用了unregisterPush,或者在MIUI上卸载了,或者超过3个月都没有和小米服务器建立过长连接,则会判定设备失效。