转自: http://www.infoq.com/cn/articles/baidu-android-cloud-push

一、推送服务简介

消息推送,顾名思义,是由一方主动发起,而另一方与发起方以某一种方式建立连接并接收消息。在Android开发中,这里的发起方我们把它叫做推送服务器(Push Server),接收方叫做客户端(Client)。相比通过轮询来获取新消息或通知,推送无论是在对客户端的资源消耗还是设备耗电量来说都比轮询要好,所以,目前绝大多数需要及时消息推送的App都采用Push的方式来进行消息通知。

身在天朝,置身墙内!Android生态系统原本提供了类似于Apple iOS推送服务APNSGCM(Google Cloud Messaging for Android),以前叫C2DM,但是由于某些原因,导致这项服务在国内不是很好使,为了弥补这个不足,并且我朝各大同胞又想使用Android推送服务,所以国内各大平台陆续推出了GCM的替代品,今天要介绍的就是其中一家,由百度提供的云推送。另外,国内做消息推送服务的还有极光推送和个推等,他们的客户包括新浪微博、淘宝等国内一线大公司。

推送的实现技术简单来说就是利用Socket维持Client和Server间的一个TCP长连接,通过这种方式能大大降低由轮询方式带来的Device的耗电量和数据访问流量。目前,百度云推送提供的推送服务支持的单一消息体大小是4k,如果超过4k,则建议在消息内携带服务请求URL进行二次请求。目前,百度云推送针对Android端提供通知推送,文本消息推送以及富媒体推送。

二、使用场景

1. 单播消息推送

Push Server向指定的设备(Device)或是用户(User)推送消息,一个用户对应一个userID,一个User可能拥有多台Device,我们希望向同一个userID推送消息时,他所有绑定了userID的Device都能收到消息。百度云推送给出的解决方案是通过Client向Push Server注册,并在Client端的监听端口取得Push Server返回的 channelIDuserIDchannelID指定一个终端,在向Push Server注册的过程中,Device可以发送IMIE码或者UUID作为唯一标示,在Push Server注册后再返回给Client生成的channelIDuserID。这两个ID获取到后由开发者自行维护,注册完毕后,Push Server维护一个注册设备列表,这个列表维护了userIDchannelID以及与Device对应的关系,当需要向指定的设备或用户推送消息时,Push Server会首先遍历这个设备列表,通过这两个ID来做唯一性判断并找到需要推送消息的Device,然后就可以进行消息推送了。

实例:用户A发表问题时,记录问题id及其对应的A的userID(或channelID),用户B发表问题回答时,通过服务端API向问题id对应的userID(或channelID)指向的Device推送答案。

2. 分组消息推送

百度云推送通过对Client设置标签(Tag)的方式来进行用户分组,Tag的产生方式可以是由Client维护也可以由Server收集,Push Server针对不同的Tag进行推送过滤,最终将消息推送到指定的Client。无论是由Client主动设置的Tag还是由Server根据用户使用习惯收集的,都由Push Server进行统一管理,在基于Tag的分组消息推送实现上,Push Server首先根据指定Tag从所有Tag下遍历出的对应的已注册的Device,从而可以获得与Device对应的userIDchannelID,继而可以针对指定Tag进行分组消息推送。对比单播消息推送,分组消息推送在推送周期上势必要长一些,并且在待推消息列表的维护上也需要做一些处理,哪些消息是推送成功的,哪些是失败的,这需要接收消息推送的Client在接收到消息后给Push Server一个消息回执,这样就保证了消息送达的准确性,如果消息推送失败,则分组列表里的待推消息会继续推送,直到推送消息成功。另外,在消息推送的实时性上,分组消息推送对比单播消息推送会根据分组消息队列的先后存在一个消息接收的延时,好比现在微信公众账号的推送,就是一个分组消息推送的实例,在消息接收的时效性上对比单播推送存在一定的延时性。

另外,还有一类消息推送使用场景,就是广播消息,该类型可以理解为分组消息的一个特列,即向所有的Tag对应的Client推送消息。广播消息是对全体集合的一个消息推送,在消息队列维护和消息推送时效性上比单个或几个Tag的分组推送成本要高。

实例:给应用提供喜好设置页面,用户勾选不同的类别,触发对应Tag的设置,这种方式是由Client主动维护Tag。或者用户阅读了某个类别的图书,触发对应Tag的设置,在服务端,给指定类别的图书设置Tag,后续会根据服务端收集的Tag给应用推送该Tag下的新书信息,这种方式就是由服务端来维护Tag分组。

三、百度云推送Android_SDK

百度提供了完整的Demo帮助开发者集成云推送服务,推送服务SDK通过.jar包和.so文件的方式可以集成到我们自己的工程中。在此之前,需要到百度开发者中心进行应用注册并获取API Key,这个作为使用推送服务应用的唯一标示,具体流程我就不赘述了,需要使用的话可以直接访问百度开发者中心进行查看。

下面主要看看Android_SDK的整体概览和内部运行机制:

上图是百度云推送Android_SDK的框架图,通过SDK可以绕过复杂的Push HTTP/HTTPS API直接和Push服务器进行交互,主要提供如下功能:

  • Push服务初始化以及Client注册绑定
  • 创建或删除标签(Tag)
  • 接收Push Server的通知并提供自定义展现消息方式
  • 推送统计分析功能,包括通知的点击和删除统计以及应用使用情况统计
  • 富媒体推送

在Android端,总共实现了三个Receiver和一个Service,其中,一个Receiver是用来处理注册绑定后接收服务端返回的channelID等信息:

1
2
3
4
5
6
7
8
9
10
<receiver android:name="com.baidu.android.pushservice.RegistrationReceiver"
android:process=": bdservice_v1">
<intent-filter>
<action android:name="com.baidu.android.pushservice.action.METHOD " />
<action android:name="com.baidu.android.pushservice.action.BIND_SYNC " />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REMOVED"/> <data android:scheme="package" />
</intent-filter>
</receiver>

第二个Receiver是用于接收系统消息以保证PushService正常运行:

1
2
3
4
5
6
7
<receiver android:name="com.baidu.android.pushservice.PushServiceReceiver" android:process=": bdservice_v1">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="com.baidu.android.pushservice.action.notification.SHOW" /> <action android:name="com.baidu.android.pushservice.action.media.CLICK" />
</intent-filter>
</receiver>

第三个Receiver就是开发者自己实现的用来接收并处理推送消息:

1
2
3
4
5
6
7
<receiver android:name="your.package.PushMessageReceiver"> <intent-filter>
<!-- 接收 push 消息 -->
<action android:name="com.baidu.android.pushservice.action.MESSAGE" />
<!-- 接收 bind、setTags 等 method 的返回结果 -->
<action android:name="com.baidu.android.pushservice.action.RECEIVE" />
</intent-filter>
</receiver>

一个Service就是在后台运行的用于保障与Push Server维持长连接并做相关处理的后台服务:

1
2
<service android:name="com.baidu.android.pushservice.PushService"
android:exported="true" android:process=" bdservice_v1"/> <!-- push service end -->

在开发者自己需要处理的广播接收器中,可以对接收到的推送消息进行处理,Push消息通过 action为com.baidu.android.pushservice.action.MESSAGE的Intent把数据发送给客户端your.package.PushMessageReceiver,消息格式由应用自己决定,PushService只负责把服务器下发的消息以字符串格式透传给客户端。接口调用回调通过action为com.baidu.android.pushservice.action.RECEIVE的Intent 返回给your.package.PushMessageReceiver。

PushMessageReceiver.java

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消息处理receiver
 * @Author Ryan
 * @Create 2013-8-6 下午5:59:38
 */
public class PushMessageReceiver extends BroadcastReceiver {  public static final String TAG = PushMessageReceiver.class.getSimpleName();

  @Override
  public void onReceive(final Context context, Intent intent) {
      if (intent.getAction().equals(PushConstants.ACTION_MESSAGE)) {          //获取消息内容
          String message = intent.getExtras().getString(
                  PushConstants.EXTRA_PUSH_MESSAGE_STRING);
          //消息的用户自定义内容读取方式
          Log.i(TAG, "onMessage: " + message);

      } else if (intent.getAction().equals(PushConstants.ACTION_RECEIVE)) {          //处理绑定等方法的返回数据
          //PushManager.startWork()的返回值通过PushConstants.METHOD_BIND得到

          //获取方法
          final String method = intent
                  .getStringExtra(PushConstants.EXTRA_METHOD);
          //方法返回错误码。若绑定返回错误(非0),则应用将不能正常接收消息。
          //绑定失败的原因有多种,如网络原因,或access token过期。
          //请不要在出错时进行简单的startWork调用,这有可能导致死循环。
          //可以通过限制重试次数,或者在其他时机重新调用来解决。
          final int errorCode = intent
                  .getIntExtra(PushConstants.EXTRA_ERROR_CODE,
                          PushConstants.ERROR_SUCCESS);
          //返回内容
          final String content = new String(
                  intent.getByteArrayExtra(PushConstants.EXTRA_CONTENT));

          //用户在此自定义处理消息,以下代码为demo界面展示用
          Log.d(TAG, "onMessage: method : " + method);
          Log.d(TAG, "onMessage: result : " + errorCode);
          Log.d(TAG, "onMessage: content : " + content);

      }
  }

}

通过在入口Activity的onCreate方法中进行推送服务的注册绑定后,即可在推送管理后台或是自己的应用服务器上进行消息推送的操作了。

1
PushManager.startWork(getApplicationContext(),PushConstants.LOGIN_TYPE_API_KEY, "you_api_key");

另外,云推送提供php、java等Server端的SDK供开发者在自己的服务器上实现推送服务进行定制化管理和操作。

四、单服务单通道机制

百度云推送实现了单服务单通道的机制,如果在一台Device上安装了多款Push SDK的应用,不会为每个应用都创建PushService,而是会采用多应用共享一个PushService的模式。这样既能减少资源消耗也能降低网络流量。PushService运行于一个独立进程,没有和主进程运行于同一进程,所以主进程不需要常驻内存,当有新的Push消息时,PushService会通过Intent发送消息给主进程进行处理。通过Intent,以指定目标应用包名的方式,发送私有消息给应用。应用即不能接收不属于自己的消息,也不能截取别人的消息,同时又降低了消耗,如下为示意图:

Android推送服务——百度云推送相关推荐

  1. 消息推送之百度云推送Android集成与使用方法

    这两天由于项目需要,研究了一下百度云推送,本来这事没什么多大工作量的,但注册百度开发者账户创建应用令我蛋疼菊紧了好一阵,这些东西做了对技术没啥提升,不做又不行,必经之路.好在我耗费了N多个毫毫秒秒后稀 ...

  2. Java后端实现安卓/IOS移动端消息推送(百度云推送)

    本文主要介绍Java服务器端如何借助第三方推送平台(百度云推送)推送给移动端消息. 使用案例介绍: 根据客户的需求,需要做一个类似淘宝消息推送的功能,客户下订单.订单付款.订单商品已发货,以及客户完成 ...

  3. JPush极光推送 and 百度云推送

    一.极光推送 这两天在研究极光推送,极光推送是一种第三方推送,提供了比较便利的推送的方式,首先让开发者不用花人力和时间去开发后台数据返回,客户端这边只管一些配置和客户端接受消息的配置. 激光推送文档: ...

  4. java百度云推送demo_百度云推送java服务端maven安装完整demo

    /*** 推送单播通知 *@author* @Date 2017年3月2日 * @Desc*/ public classBaiduPush {publicString[] pushNotificati ...

  5. 集成百度云推送,Android8.0系统推送收不到问题解决方案

    因为之前没有集成过百度云推送,接手新项目之后项目需求是接入百度云推送,没办法因为项目是海外项目所以只能硬着头皮来接入了,话不多说开始你的表演: 首先就是去百度云推送的官网去创建应用并启用: .在配置详 ...

  6. Android百度云推送接入,附完整代码

    1.创建应用获取api_key 百度云推送:http://push.baidu.com/ SDK下载:http://push.baidu.com/sdk/push_client_sdk_for_and ...

  7. 百度云推送-服务端 C# SDK

    思路: 1.公司有项目需要做android和ios手机端推送消息的功能: 2.没有接触过这方面的知识,一头雾水,开始在网上一顿搜,网上倒是有不少解决方案,首先搜的是android的解决方案,因为ios ...

  8. 百度云推送、极光推送等云推送服务搜罗点评

    事先声明,本人只测试的android部分.ios的情况不知道. 个推 用户数量低于10000时免费,大于时收费.看很多大公司的软件都在用. "sdk接口比较丰富,使用比较简单,而且遇到问题直 ...

  9. Android推送 百度云推送 入门篇

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/27231237 现在app基本都有推送的功能,于是看了下百度云的推送,官方文档和D ...

  10. android开发(25) - 推送的实现,使用百度云推送

    什么叫推送? 中文名称:推送 英文名称:push 定义:描述因特网内容提供者和因特网用户之间工作方式的术语."推送"指因特网内容提供者定期向预订用户"提供"数据 ...

最新文章

  1. 选择创业型还是成熟型公司?
  2. redis mysql主从同步_手撕Redis,主从同步
  3. REDIS实践之请勿踩多进程共用一个实例连接的坑
  4. 《程序员》2月精彩内容:互联网应用架构面面观
  5. leetcode 27. 移除元素(双指针)
  6. 2013年蓝桥杯软件大赛预赛java本科b组答案_2013年蓝桥杯软件大赛预赛C本科B组试题...
  7. 书籍推荐:《LInux就该这么学》
  8. java获取当月共有几天_Java计算当前月有多少天以及获取当前月开始以及结束日期...
  9. 禁止文本框输入空格和回车
  10. 配置中文XeLaTex环境
  11. 如何高效学习,斯科特·扬(全文)
  12. matlab 科研绘图
  13. 雪花屏幕保护程序(VB.ENT)
  14. 手机梦幻模拟战更新服务器正在维护,梦幻模拟战手游9月13日更新了什么 梦幻模拟战更新维护公告...
  15. ADAS高级辅助驾驶视觉系统(Advanced Driver Assistant System)
  16. 不同比例,不同尺寸的笔记本屏幕对比
  17. IDEA 返回上一步,回到下一步 冲突 快捷键设置
  18. 使用STM32的DFSDM外设来驱动PDM麦克风进行音频采集
  19. 动态链表的创建、节点内存空间申请以及释放
  20. mysql全文索引中英文混合_MySQL 英文全文搜索和中文全文搜索 (FULLTEXT)

热门文章

  1. HTML页面基本结构介绍
  2. HDMI九画面视频分割器(MT-SW091)
  3. webpack源码解析系列(一)
  4. 程序员培训学多久?学半年能做程序员吗?
  5. JS中this的四种调用方法
  6. 过去式和过去分词的不规则列表
  7. python画满天星_跟我学解Python题-海龟制图满天星
  8. 机器学习大作业---文献综述
  9. javascript运算符——条件、逗号、赋值、()和void运算符 (转载)
  10. 刚学的一招呵呵,愚人节到了,教个大家最强的整人方法