友盟推送原理3.1.1 混淆配置中为什么包含华为,小米的信息

目前国内做消息推送的有云巴,百度,蝴蝶,极光,个推哪个比较好点? - 知乎918被浏览235822分享邀请回答105 条评论分享收藏感谢收起31 条评论分享收藏感谢收起更多21 个回答被折叠()关于推送的一些补充 - 知乎专栏
{"debug":false,"apiRoot":"","paySDK":"/api/js","wechatConfigAPI":"/api/wechat/jssdkconfig","name":"production","instance":"column","tokens":{"X-XSRF-TOKEN":null,"X-UDID":null,"Authorization":"oauth c3cef7c66aa9e6a1e3160e20"}}
{"database":{"Post":{"":{"title":"关于推送的一些补充","author":"stormzhang","content":"昨天的文章「」不少人的留言有不同的声音,这里补充一下,顺便表示下我的不服!\n
1. 收了小米多少钱?很多人留言表示这软广不错,收了小米多少钱?不管你们是开玩笑还是认真的,我只想告诉你们,这篇文章是我自己的实践加上业内同行的交流总结出来的,没有任何人给我钱,而且我自己不是米粉,本身是不愿意推荐任何产品的,我完全是抱着能帮你们解决问题的角度出发的,等你们实际中遇到这个问题你们就会明白我文章中的观点了。\n
认为我是软广的我表示不服,我之前确实发过一些广告,而且我甚至希望多些广告商找我,毕竟没人愿意跟钱过不去,但是我都是堂堂正正的发,光明正大的告诉你们,是广告的从不藏着掖着!另外,小米,你丫的欠我一条广告费!\n
我很欣赏一些质疑文中观点,然后给我留言有理有据摆事实讲道理的行为,我的观点不一定正确,毕竟一家之言,但是能一起探讨我是完全乐意的,比如有人给我提了以下几个观点,我觉得很有意义,这里补充下:\n
2. 友盟的数据可靠么?讲真,没有任何数据来源是绝对可靠的,目前国内大多数 app 的数据统计基本都是用的友盟,也就意味着友盟的数据不是绝对正确的,但是起码数据来源参考作用非常大,如果你能给我提供一个更靠谱的数据来源,那不妨可以结合下,否则,我宁愿相信友盟的数据。\n
3. 根据市场份额来选择推送?友盟的那份数据小米市场份额第一,但是紧跟其后的三星、华为等市场份额加起来比小米要多,如果以市场份额来选择推送为什么只认准小米呢?\n
关于这点我文中说的很清楚,小米推送的优势是在 MIUI 系统不会被杀死,这个绝对的优势加上他的市场份额,才会推荐优先选择小米。三星市场份额也很大,但是你没有这个优势,对于三星手机,选择小米推送还是信鸽推送没绝对性的区别。\n
所以我文中的结论是:如果你只能选择一种推送的话,那么建议优先选择小米。如果你想更优化的话完全可以根据不同渠道选择不同的提送方案。\n
4. 自己写推送可以么?当然可以,但是不建议这么做,一是浪费资源,二是即使你有资源有能力去自己实现,但是你被杀死之后你很难启动。而使用第三方服务之后,有互相唤醒机制,只要有一个集成了该推送的 app 被用户打开,那么你家的 app 就会被唤醒,避免了永远保持沉默。你自己做的话就没有这优势,除非,你们有阿里、百度这样的全家桶。\n
5. 腾讯信鸽能被微信唤醒么?信鸽推送号称是微信的推送解决方案,但是注意只是说是用了微信的解决方案,并不是说微信也用的信鸽推送,这两者有天壤之别,所以那些幻想集成信鸽之后就能被微信唤醒的还是洗洗睡吧。\n
另外很多人纳闷为什么微信的服务不会被杀死?因为技术很牛逼么?\n
微信的技术确实很牛逼,在保活上面做了很多优化,但是不管你做的如何牛逼,某些 rom 系统级别的依然可以把你干掉。那为什么感觉微信永远不会被杀死呢?\n
其实最重要的一个原因是微信已经是各大厂商的白名单了,很多手机甚至出厂系统自带微信,对它的服务有特殊照顾。所以别幻想着能做成跟微信一样牛逼不被杀死,也别幻想着集成信鸽就能靠微信能把你家 app 唤醒。\n
6. 最后我的所有文章都是我一家之言,没有权威性质,你完全可以质疑,也欢迎探讨,毕竟技术本身就需要交流才能共同进步。但是你没有任何理由的一顿乱喷,说我写的垃圾,什么玩意,好歹说个理由吧,让你写又写不出来,你再牛逼,不分享出来有什么用?觉得垃圾的大可以取关,毕竟没人逼着你看,也没人问你收费,我这里不欢迎「嘴强王者」!最最后,再牛的保活方案都不能真正保活,充其量是多撑一会,这反而还会加重系统负担且耗电,如果你的产品本身很糟糕,这反而更激发用户卸载你的 app ,Android 的后台已经一团糟,这点跟 iOS 比简直相差太远,希望大家不要再去迫害它,改善体验,优化自家 app 才是正道!本文原创发布于微信公众号 AndroidDeveloper「googdev」,不仅是Android原创干货分享,也许是最有人情味的技术公众号,转载请务必注明出处!","updated":"T05:59:45.000Z","canComment":false,"commentPermission":"anyone","commentCount":20,"collapsedCount":0,"likeCount":39,"state":"published","isLiked":false,"slug":"","isTitleImageFullScreen":false,"rating":"none","titleImage":"/f82abd4ad0dfb84e096fd80_r.jpg","links":{"comments":"/api/posts//comments"},"reviewers":[],"topics":[{"url":"/topic/","id":"","name":"Android"},{"url":"/topic/","id":"","name":"Android 开发"}],"adminClosedComment":false,"titleImageSize":{"width":800,"height":600},"href":"/api/posts/","excerptTitle":"","column":{"slug":"stormzhang","name":"stormzhang"},"tipjarState":"inactivated","annotationAction":[],"sourceUrl":"","pageCommentsCount":20,"snapshotUrl":"","publishedTime":"T13:59:45+08:00","url":"/p/","lastestLikers":[{"bio":"Android程序员","isFollowing":false,"hash":"0eb14bbd097c6affbdb98c00082cf7eb","uid":938200,"isOrg":false,"slug":"wang-yuan-39-70-57","isFollowed":false,"description":"","name":"王元","profileUrl":"/people/wang-yuan-39-70-57","avatar":{"id":"f6c834d0a33e7fe6de1e","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"谷歌粉,android开发者,专注app开发架构","isFollowing":false,"hash":"eb274aee1a8d","uid":52,"isOrg":false,"slug":"sheng-fu-qiang","isFollowed":false,"description":"/ShengFQ","name":"盛富强","profileUrl":"/people/sheng-fu-qiang","avatar":{"id":"2eab7d1eed07bf9eb52fc","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"自己动手,丰衣足食。","isFollowing":false,"hash":"6fd4d4fb72ddf374c4a5","uid":88,"isOrg":false,"slug":"shu-dai-ma-zhu-xian-sen-si","isFollowed":false,"description":"泯然众人矣。","name":"忄代码丶先森灬","profileUrl":"/people/shu-dai-ma-zhu-xian-sen-si","avatar":{"id":"b48902a6afe1c3da628473f","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"","isFollowing":false,"hash":"5dcf1b1de101d","uid":80,"isOrg":false,"slug":"he1s","isFollowed":false,"description":"","name":"He1S","profileUrl":"/people/he1s","avatar":{"id":"bb3a05f43a55","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"","isFollowing":false,"hash":"d7d74bb9afa","uid":68,"isOrg":false,"slug":"ling-yun-xuan-ya","isFollowed":false,"description":"","name":"凌云轩雅","profileUrl":"/people/ling-yun-xuan-ya","avatar":{"id":"d4a2059e6","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false}],"summary":"昨天的文章「」不少人的留言有不同的声音,这里补充一下,顺便表示下我的不服!\n 1. 收了小米多少钱?很多人留言表示这软广不错,收了小米多少钱?不管你们是开玩笑还是认真的,我只想告诉你们,这篇文章是我自己的实践加上业内同行…","reviewingCommentsCount":0,"meta":{"previous":{"isTitleImageFullScreen":false,"rating":"none","titleImage":"/77df3cb15b1ac0bce056da8_r.jpg","links":{"comments":"/api/posts//comments"},"topics":[{"url":"/topic/","id":"","name":"Android"},{"url":"/topic/","id":"","name":"Android 开发"}],"adminClosedComment":false,"href":"/api/posts/","excerptTitle":"","author":{"bio":"微信公众号: stormzhang","isFollowing":false,"hash":"926fa049f","uid":08,"isOrg":false,"slug":"stormzhang","isFollowed":false,"description":"个人博客:\n微信公众号: stormzhang\n不接受私信,有事公众号留言。","name":"stormzhang","profileUrl":"/people/stormzhang","avatar":{"id":"20d8a65bfbbeb","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},"column":{"slug":"stormzhang","name":"stormzhang"},"content":"之前在群里有同学问我关于推送的一些问题,解答之后我觉得这个话题还挺有用,因为几乎大部分人都会遇到这个问题,那姑且就写篇文章总结给你们吧。
1. 为什么要用推送?推送功能可谓是现如今任何一个 App 的必备功能,因为每天可以推送消息,提升日活啊,用户长久没打开了,推个消息就把用户召回了啊。一般来说推送都是系统来做的,比如 iOS 的推送是苹果自己做的,系统级别的,任何时候都可以推送给用户。
而 Android 的推送本来 Google 自己也有一套推送服务,也是系统级别的,叫做 GCM ,Google Cloud Messaging,但是众所周知,Google 的服务在国内根本没法使用,也就意味着我们不得不用第三方的推送服务。
2. 为什么要使用第三方推送服务?因为 GCM 在国内的限制,所以这块也就是一个机会了,国内因此也衍生了很多推送服务公司。
大部分公司都会选择使用第三方推送服务,因为推送这个事自己做还挺麻烦的,需要服务器资源,开发以及后台管理、统计等,对于一些大公司来说本身有资源做这个事,而且出于安全考虑也会优先自己做,但是大部分中小型公司是不会浪费资源在这块的,尤其创业公司,还是把资源用在自己的核心业务上更急迫,所以大部分中小型互联网公司都会选择第三方推送服务。
3. 有哪些第三方的服务?
目前来说做的比较好的推送服务大概有小米推送、腾讯信鸽推送、百度推送、极光推送、友盟推送等。这些推送服务大都有以下特点:
免费当然部分公司也有收费的,号称更稳定、推送到达率更高,但大部分都还是用的免费版。
服务会被杀死由于 Android 系统的机制,后台推送 Service 会被各种主动的或是被动的行为给杀死,而服务一旦被杀死,意味着就接收不到推送消息。
多个 app 共用一条推送通道什么意思呢?就是如果有多个 app 都使用了同一家推送服务,那么这些 app 共用一条消息通道,即使你家的 app 推送服务被杀死了,那么只要用户打开了其他集成该推送服务的 app ,你家的推送就能接受到消息。
4. 哪家推送更好呢?每家的推送服务都号称推送到达率很高,号称自己家的推送服务更不容易被杀死,号称自己的推送更稳定更有保证,然而我要说的是,各家都差不多,技术上你能实现的,别家一样能实现,到达率也都差不多,据我观察平均推送到达率能达到 70% 左右都算不错的了,那么到底该怎么选择呢?
有一点比较特殊的是?有些推送服务有自己家品牌的手机,比如小米有自己的手机,而在 MIUI 系统上小米推送是作为系统级的服务,不会被杀死,毕竟一家人,总不至于傻到把自己家的服务给干掉吧?所以这就是一个巨大的优势了。类似的华为推送服务在自己家的手机系统上也不会被杀死。各大手机厂商都宣传自己家的手机市场份额第一,然而我要说的是如今市场上的 Android 手机只分小米手机跟其他手机,什么意思?就是小米手机是目前市场份额第一,而且远远领先其他手机,这个在我们自己家 app 的数据上看就是这样,而这里有一份友盟发布的 Android 设备活跃的排名数据,地址在这里:方便大家查看我截了张图:
上图可以看到,前十排名小米占了 7 席,总体小米手机确实是市场份额第一,其次是三星、华为紧随其后,接着 oppo、vivo、魅族平分秋色。
所以小米手机的市场份额,加上小米推送在 MIUI 上不被杀死这一大特性,致使选择小米推送是第一选择。
所以综合下来,如果你的 app 想省事的话那么建议直接集成小米推送。
如果你的 app 想要把推送更优化下,那么可以集成多个推送服务,针对不同的渠道用不同的推送,比如小米渠道用小米推送,华为渠道用华为推送,其他渠道用信鸽推送等,但是这种也比较麻烦,具体怎么做看你们自己的权衡了。
PS: 我以我 stormzhang 的帅来保证,本篇文章绝对没收任何广告费,全都是自己实践下来的良心推荐!本文原创发布于微信公众号 AndroidDeveloper「googdev」,不仅是Android原创干货分享,也许是最有人情味的技术公众号,转载请务必注明出处!","state":"published","sourceUrl":"","pageCommentsCount":0,"canComment":false,"snapshotUrl":"","slug":,"publishedTime":"T00:20:06+08:00","url":"/p/","title":"Android 推送到底哪家强","summary":"之前在群里有同学问我关于推送的一些问题,解答之后我觉得这个话题还挺有用,因为几乎大部分人都会遇到这个问题,那姑且就写篇文章总结给你们吧。 1. 为什么要用推送?推送功能可谓是现如今任何一个 App 的必备功能,因为每天可以推送消息,提升日活啊,用…","reviewingCommentsCount":0,"meta":{"previous":null,"next":null},"commentPermission":"anyone","commentsCount":0,"likesCount":0},"next":{"isTitleImageFullScreen":false,"rating":"none","titleImage":"/f3e069bb77b0c799db2ff5f6eee7859b_r.jpg","links":{"comments":"/api/posts//comments"},"topics":[{"url":"/topic/","id":"","name":"Android"},{"url":"/topic/","id":"","name":"Android 开发"}],"adminClosedComment":false,"href":"/api/posts/","excerptTitle":"","author":{"bio":"微信公众号: stormzhang","isFollowing":false,"hash":"926fa049f","uid":08,"isOrg":false,"slug":"stormzhang","isFollowed":false,"description":"个人博客:\n微信公众号: stormzhang\n不接受私信,有事公众号留言。","name":"stormzhang","profileUrl":"/people/stormzhang","avatar":{"id":"20d8a65bfbbeb","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},"column":{"slug":"stormzhang","name":"stormzhang"},"content":"好文优秀开源项目可能是你见过的最酷炫的加载动画。酷炫的碎纸机动画。一个 简单、优雅、易用 的滚动数字控件!Android水波动画帮助类,一行代码实现View显示/隐藏/startActivity特效。一个支持四个方向循环滚动的自定义控件。本文原创发布于微信公众号 AndroidDeveloper「googdev」,不仅是Android原创干货分享,也许是最有人情味的技术公众号,转载请务必注明出处!","state":"published","sourceUrl":"","pageCommentsCount":0,"canComment":false,"snapshotUrl":"","slug":,"publishedTime":"T20:26:57+08:00","url":"/p/","title":"AndroidDeveloper Weekly No.2","summary":"好文优秀开源项目可能是你见过的最酷炫…","reviewingCommentsCount":0,"meta":{"previous":null,"next":null},"commentPermission":"anyone","commentsCount":0,"likesCount":0}},"annotationDetail":null,"commentsCount":20,"likesCount":39,"FULLINFO":true}},"User":{"stormzhang":{"isFollowed":false,"name":"stormzhang","headline":"个人博客:\n微信公众号: stormzhang\n不接受私信,有事公众号留言。","avatarUrl":"/20d8a65bfbbeb_s.jpg","isFollowing":false,"type":"people","slug":"stormzhang","bio":"微信公众号: stormzhang","hash":"926fa049f","uid":08,"isOrg":false,"description":"个人博客:\n微信公众号: stormzhang\n不接受私信,有事公众号留言。","profileUrl":"/people/stormzhang","avatar":{"id":"20d8a65bfbbeb","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false,"badge":{"identity":null,"bestAnswerer":null}}},"Comment":{},"favlists":{}},"me":{},"global":{},"columns":{"stormzhang":{"following":false,"canManage":false,"href":"/api/columns/stormzhang","name":"stormzhang","creator":{"slug":"stormzhang"},"url":"/stormzhang","slug":"stormzhang","avatar":{"id":"02ad8fdce4cac9a8a8d4","template":"/{id}_{size}.jpeg"}}},"columnPosts":{},"postComments":{},"postReviewComments":{"comments":[],"newComments":[],"hasMore":true},"favlistsByUser":{},"favlistRelations":{},"promotions":{},"switches":{"couldAddVideo":false},"draft":{"titleImage":"","titleImageSize":{},"isTitleImageFullScreen":false,"canTitleImageFullScreen":false,"title":"","titleImageUploading":false,"error":"","content":"","draftLoading":false,"globalLoading":false,"pendingVideo":{"resource":null,"error":null}},"config":{"userNotBindPhoneTipString":{}},"recommendPosts":{"articleRecommendations":[],"columnRecommendations":[]},"env":{"isAppView":false,"appViewConfig":{"content_padding_top":128,"content_padding_bottom":56,"content_padding_left":16,"content_padding_right":16,"title_font_size":22,"body_font_size":16,"is_dark_theme":false,"can_auto_load_image":true,"app_info":"OS=iOS"},"isApp":false},"sys":{}}Android(56)
这几天接了一下友盟,小米,华为三方的推送。
总的流程下来,小米的api是最友好的,华为的文档和demo有点脱节。这两个推送在特定的手机上都挺稳定的的。
友盟的就有点麻烦,过程中遇到几个问题
1,接入友盟之后,APK方法数超过64K了
compileSdkVersion 21
buildToolsVersion "21.1.0"
defaultConfig {
minSdkVersion 14
targetSdkVersion 21
// Enabling multidex support.
multiDexEnabled true
dependencies {
compile 'com.android.support:multidex:1.0.0'
MultiDex.install(getTargetContext());
2,第二个问题是要自定义点击通知栏要调整到特定页面,需要重写
public void dealWithNotificationMessage(Context context, UMessage msg){
if ( msg.extra == null) {
super.dealWithNotificationMessage(context, msg)
Notification notification = new Notification.Builder(context)
.setContentTitle(msg.title)
.setContentText(msg.text)
.setSmallIcon(R.drawable.share_default_logo)
notification.flags |= FLAG_AUTO_CANCEL
notification.defaults = DEFAULT_ALL
notification.ledARGB = Color.BLUE
notification.ledOnMS = 5000
((NotificationManager) SeeYouApp.getInstance().getSystemService(NOTIFICATION_SERVICE)
).notify(0, notification)
3,要识别一下友盟的channel进程,允许它注册。
测试起来很麻烦,因为杀应用,如果我们原有的进程没有被杀,那么友盟的推送就不会被杀,我们的进程被杀,友盟也被杀。这叫我怎么测…后来同事提醒,可以相互唤醒。
所以就是安装一个友盟的官方的App,然后设置允许相互唤醒(这个各个手机的设置都不同,在设置里面找相互唤醒类似的字眼)
后台那边就是判断一下原有通道是不是通的,如果不通就走第三方渠道。
之前一直在测弱网络,所以我以为会有一个心跳的误差。其实杀APP,后台立刻就能知道长连接断了,因为socket断了,系统会发eof(从抓包上看就是FIN)。
5,其他有的没的
华为只支持企业级应用,所以我是用公司账号注册两个app,去测试的。华为客户端这边的识别就直接是包名,要有手机卡,手机必须是华为手机才能推到。
小米接入小米推送之后,手动杀进程居然只杀了前台应用,得去应用里面强制关闭。没接入之前我记得手动杀进程是什么都不剩的,也许是官方推送保活福利吧。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:103368次
积分:1897
积分:1897
排名:千里之外
原创:129篇
转载:20篇
评论:16条公司的 app 一直使用的是极光推送,最近反馈比较多的是推送消息收不到,看来需要找新的推送服务了,在国内目前手机品牌占有率比较多的是华为和小米,且这两家都有自己的推送服务,同时一个合作的友商说他们使用的是友盟推送,推送率还不错,那么就测试这三个推送服务了。
按照集成的难易程度排序
官网有提供了视频和文档,很详细,而且很简单。
在小米推送运营平台创建应用,, 获取到 AppID , AppKey
把从小米下载的 jar 放到 libs 下
在 AndroidManifest.xml 中添加权限
&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="com.xxx.xxx.permission.MIPUSH_RECEIVE" android:protectionLevel="signature" /&
&uses-permission android:name="com.xxx.xxx.permission.MIPUSH_RECEIVE" /&
配置推送服务需要的service和receiver
android:enabled="true"
android:process=":pushservice"
android:name="com.xiaomi.push.service.XMPushService"/&
android:name="com.xiaomi.push.service.XMJobService"
android:enabled="true"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE"
android:process=":pushservice" /&
&!--注:此service必须在3.0.1版本以后(包括3.0.1版本)加入--&
android:enabled="true"
android:exported="true"
android:name="com.xiaomi.mipush.sdk.PushMessageHandler" /&
&service android:enabled="true"
android:name="com.xiaomi.mipush.sdk.MessageHandleService" /&
&!--注:此service必须在2.2.5版本以后(包括2.2.5版本)加入--&
android:exported="true"
android:name="com.xiaomi.push.service.receivers.NetworkStatusReceiver" &
&intent-filter&
&action android:name="android.net.conn.CONNECTIVITY_CHANGE" /&
&category android:name="android.intent.category.DEFAULT" /&
&/intent-filter&
&/receiver&
android:exported="false"
android:process=":pushservice"
android:name="com.xiaomi.push.service.receivers.PingReceiver" &
&intent-filter&
&action android:name="com.xiaomi.push.PING_TIMER" /&
&/intent-filter&
&/receiver&
自定义一个BroadcastReceiver类
public class MiMessageReceiver extends PushMessageReceiver {
private static final String TAG = "MiMessageReceiver";
private String mRegId;
private String mT
private String mA
private String mA
private String mStartT
private String mEndT
public void onNotificationMessageClicked(Context context, MiPushMessage message) {
Log.v(MyApplication.TAG,
"onNotificationMessageClicked is called. " + message.toString());
if (!TextUtils.isEmpty(message.getTopic())) {
mTopic = message.getTopic();
Log.e(TAG, mTopic);
} else if (!TextUtils.isEmpty(message.getAlias())) {
mAlias = message.getAlias();
Log.e(TAG, mAlias);
public void onNotificationMessageArrived(Context context, MiPushMessage message) {
Log.v(MyApplication.TAG,
"onNotificationMessageArrived is called. " + message.toString());
String log = "Arrived a notification message. Content is " + message.getContent();
if (!TextUtils.isEmpty(message.getTopic())) {
mTopic = message.getTopic();
} else if (!TextUtils.isEmpty(message.getAlias())) {
mAlias = message.getAlias();
public void onCommandResult(Context context, MiPushCommandMessage message) {
Log.v(TAG,
"onCommandResult is called. " + message.toString());
String command = message.getCommand();
List&String& arguments = message.getCommandArguments();
String cmdArg1 = ((arguments != null && arguments.size() & 0) ? arguments.get(0) : null);
String cmdArg2 = ((arguments != null && arguments.size() & 1) ? arguments.get(1) : null);
if (MAND_REGISTER.equals(command)) {
if (message.getResultCode() == ErrorCode.SUCCESS) {
mRegId = cmdArg1;
Log.e(TAG, "Register push success.");
Log.e(TAG, "Register push fail.");
log = message.getReason();
public void onReceiveRegisterResult(Context context, MiPushCommandMessage message) {
Log.v(TAG,
"onReceiveRegisterResult is called. " + message.toString());
String command = message.getCommand();
List&String& arguments = message.getCommandArguments();
String cmdArg1 = ((arguments != null && arguments.size() & 0) ? arguments.get(0) : null);
if (MAND_REGISTER.equals(command)) {
if (message.getResultCode() == ErrorCode.SUCCESS) {
mRegId = cmdArg1;
Log.e(TAG, "Register push success.");
Log.e(TAG, "Register push fail.");
在 AndroidManifest.xml 中注册该广播
android:name=".MiMessageReceiver"
android:exported="true"&
&intent-filter&
&action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE"/&
&/intent-filter&
&intent-filter&
&action android:name="com.xiaomi.mipush.MESSAGE_ARRIVED"/&
&/intent-filter&
&intent-filter&
&action android:name="com.xiaomi.mipush.ERROR"/&
&/intent-filter&
&/receiver&
在 Application 中初始化推送服务
private void initMiPush() {
//初始化push推送服务
if (shouldInit()) {
MiPushClient.registerPush(this, MI_APP_ID, MI_APP_KEY);
LoggerInterface newLogger = new LoggerInterface() {
public void setTag(String tag) {
public void log(String content, Throwable t) {
Log.d(TAG, content, t);
public void log(String content) {
Log.d(TAG, content);
Logger.setLogger(this, newLogger);
private boolean shouldInit() {
ActivityManager am = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));
List&ActivityManager.RunningAppProcessInfo& processInfos = am.getRunningAppProcesses();
String mainProcessName = getPackageName();
int myPid = android.os.Process.myPid();
for (ActivityManager.RunningAppProcessInfo info : processInfos) {
if (info.pid == myPid && mainProcessName.equals(info.processName)) {
接入步骤(HMS-SDK版本:2.4.0.300):
把从华为 Push 推送官网下载的 aar ,位于:...\HMS-2.4.0.300\HWHMS-SDK-v2.4.0.300\libs\HMS-SDK-2.4.0.300.aar,放到工程目录的 aars 下(没有该目录的新建一个)
在 AndroidManifest.xml 文件的 Application 节点添加: meta-data 和自定义的 Receiver,如下(其中 meta-data 中的 appId 是在网页上创建应用的 id,我的是一个 8 位的数字):
&meta-data
android:name="com.huawei.hms.client.appid"
android:value="appId"&
&/meta-data&
&!-- 第三方相关 :接收Push消息(注册、Push消息、Push连接状态)广播 --&
&receiver android:name=".HuaweiPushReceiver"&
&intent-filter&
&!-- 必须,用于接收token --&
&action android:name="com.huawei.android.push.intent.REGISTRATION"/&
&!-- 必须,用于接收消息 --&
&action android:name="com.huawei.android.push.intent.RECEIVE"/&
&!-- 可选,用于点击通知栏或通知栏上的按钮后触发onEvent回调 --&
&action android:name="com.huawei.android.push.intent.CLICK"/&
&!-- 可选,查看push通道是否连接,不查看则不需要 --&
&action android:name="com.huawei.intent.action.PUSH_STATE"/&
&/intent-filter&
&meta-data
android:name="CS_cloud_ablitity"
android:value="@string/hwpush_ability_value"/&
&/receiver&
在 AndroidManifest.xml 文件中添加权限
&uses-permission android:name="android.permission.READ_PHONE_STATE" /&
&uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /&
&uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /&
&uses-permission android:name="android.permission.WAKE_LOCK" /&
&uses-permission android:name="android.permission.INTERNET"/&
&uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/&
在 MainActivity 或者 BaseAcitivty 中初始化华为 Push ,放在 onCreate() 中初始化华为 Push
private void initHuaweiPush(Context context) {
HuaweiIdSignInOptions options = new HuaweiIdSignInOptions.Builder(HuaweiIdSignInOptions.DEFAULT_SIGN_IN)
mClient = new HuaweiApiClient.Builder(context)
.addApi(HuaweiPush.PUSH_API)
.addConnectionCallbacks(new HuaweiApiClient.ConnectionCallbacks() {
public void onConnected() {
getToken();
runOnUiThread(new Runnable() {
public void run() {
tv.setText("HUAWEI onConnected, IsConnected: " + mClient.isConnected());
Log.e(TAG, "HUAWEI onConnected, IsConnected: " + mClient.isConnected());
public void onConnectionSuspended(final int i) {
runOnUiThread(new Runnable() {
public void run() {
tv.setText("HUAWEI onConnectionSuspended, cause: " + i + ", IsConnected:" +
mClient.isConnected());
Log.e(TAG, "HUAWEI onConnectionSuspended, cause: " + i + ", IsConnected:" +
mClient.isConnected());
.addOnConnectionFailedListener(new HuaweiApiClient.OnConnectionFailedListener() {
public void onConnectionFailed(@NonNull final ConnectionResult
connectionResult) {
runOnUiThread(new Runnable() {
public void run() {
tv.setText("HUAWEI onConnectionFailed, ErrorCode: " + connectionResult.getErrorCode());
Log.e(TAG, "HUAWEI onConnectionFailed, ErrorCode: " + connectionResult.getErrorCode());
mClient.connect();
protected void onStart() {
super.onStart();
mClient.connect();
private void getToken() {
if (!isConnected()) {
tv.setText("get token failed, HMS is disconnect.");
// 同步调用方式,不会返回token,通过广播的形式返回。
new Thread(new Runnable() {
public void run() {
PendingResult&TokenResult& token = HuaweiPush.HuaweiPushApi.getToken(mClient);
token.await();
}).start();
public boolean isConnected() {
if (mClient != null && mClient.isConnected()) {
新建 HuaweiPushReceiver ,继承 PushReceiver,重写 onToken() ,onPushMsg(),onEvent(),onPushState(),在 onToken() 中可以获取到 token。
public class HuaweiPushReceiver extends PushReceiver {
private static final String TAG = "Huawei PushReceiver";
public void onToken(Context context, String token, Bundle extras) {
String belongId = extras.getString("belongId");
String content = "get token and belongId successful, token = " + token + ",belongId = " + belongId;
Log.d(TAG, content);
public boolean onPushMsg(Context context, byte[] msg, Bundle bundle) {
String content = "-------Receive a Push pass-by message: " + new String(msg, "UTF-8");
Log.d(TAG, content);
} catch (Exception e) {
e.printStackTrace();
public void onEvent(Context context, PushReceiver.Event event, Bundle extras) {
if (Event.NOTIFICATION_OPENED.equals(event) || Event.NOTIFICATION_CLICK_BTN.equals(event)) {
int notifyId = extras.getInt(BOUND_KEY.pushNotifyId, 0);
if (0 != notifyId) {
NotificationManager manager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(notifyId);
String content = "--------receive extented notification message: " + extras.getString
(BOUND_KEY.pushMsgKey);
Log.d(TAG, content);
super.onEvent(context, event, extras);
public void onPushState(Context context, boolean pushState) {
String content = "---------The current push status: " + (pushState ? "Connected" :
"Disconnected");
Log.d(TAG, content);
} catch (Exception e) {
e.printStackTrace();
获取到 token 以后就连接成功了。可以测试推送了。
非华为手机使用华为推送需要安装-华为移动服务.apk
各个版本EMUI对push的支持情况
华为手机上:
Emui3.0上,Push广播有很大概率被限制,如: Mate7 3.0版本,荣耀6plus,P7 3.0版本,4X, 4A等。
Emui3.1上,Push广播基本不被限制,但个别型号机型存在问题,如:荣耀5x等。
Emui4.0及以上,Push广播有较高概率被限制,不被限制的机型如:荣耀畅玩4C,荣耀畅玩4X,Mate S,P8 MAX等。
Emui4.1 , ROM升级到了最新版本的(80%已升),通知消息不走广播,不会被限制,透传消息走广播,会被限制。
Emui5.0以上 ,通知消息不走广播,不会被限制,透传消息走广播,会被限制。
如广播被限制,需要将应用设为开机启动项。所以对于及时性或到达率要求非常高的应用,我们建议应用要考虑替代方案。
非华为手机:
第三方手机(如:小米、OPPO、三星等),由于rom的限制,需要将应用 设为开机启动项。
Samsung S4(Android 5.0)
HTC D820u(Android 6.0)
Huawei P8(Android 6.0)
Xiaomi Note(Android 7.0)
Samsung S7(Android 7.0)
LG Nexus 6(Android 7.0)
Huawei Mate8(Android 7.0)
Huawei Mate9(Android 7.0)
三家推送比较
华为推送在非华为手机上必须安装华为移动服务,这点比较的坑,用户可能不会同意安装的,那就没得玩了,只适合在华为手机上使用。
华为推送还得区别 Emui 的版本,这玩意也不是个小坑,虽然官方QQ群公告说 Emui 5.0 以后都可以收到消息推送,但是不知道靠谱不靠谱
友盟推送的话,在测试阶段,发现三星S7(Android 7.0),三星S4(Android 5.0),华为P8(Android 6.0)无法获取到 token,没有 token ,那就推送不了了。
小米推送还可以,但是在三星 S4(Android 5.0) 上无法接收到推送。
综上,app 需要集成华为推送和小米推送比较的靠谱点,针对华为手机使用华为推送,其他手机使用小米推送。
使用中的大坑,在华为手机上假如华为移动服务不是最新版本或者被卸载了,推送服务无法使用。必须在 app 中提示用户更新或安装,真是一个大坑,关键是更新界面丑的要死,还会出现更新失败的情况,坑人呀。
针对小米推送,在非小米设备上会出现重启以后无法获得推送,因为是重启以后,小米的 XMPushService 没有起来,目前采用的办法是监听手机启动广播,然后启动小米的 XMPushService。
阅读(...) 评论()

我要回帖

更多关于 友盟推送 java服务端 的文章

 

随机推荐