- 浏览: 1482024 次
- 性别:
- 来自: 南京
文章分类
- 全部博客 (419)
- XMPP (19)
- Android (180)
- Java (59)
- Network (4)
- HTML5 (13)
- Eclipse (9)
- SCM (23)
- C/C++ (4)
- UML (4)
- Libjingle (15)
- Tools&Softwares (29)
- Linphone (5)
- Linux&UNIX (6)
- Windows (18)
- Google (10)
- MISC (3)
- SIP (6)
- SQLite (5)
- Security (4)
- Opensource (29)
- Online (2)
- 文章 (3)
- MemoryLeak (10)
- Decompile (5)
- Ruby (1)
- Image (1)
- Bat (4)
- TTS&ASR (28)
- Multimedia (1)
- iOS (20)
- Asciiflow - ASCII Flow Diagram Tool.htm (1)
- Networking (1)
- DLNA&UPnP (2)
- Chrome (2)
- CI (1)
- SmartHome (0)
- CloudComputing (1)
- NodeJS (3)
- MachineLearning (2)
最新评论
-
bzhao:
点赞123!
Windows的adb shell中使用vi不乱码方法及AdbPutty -
wahahachuang8:
我觉得这种东西自己开发太麻烦了,就别自己捣鼓了,找个第三方,方 ...
HTML5 WebSocket 技术介绍 -
obehavior:
view.setOnTouchListenerview是什么
[转]android 一直在最前面的浮动窗口效果 -
wutenghua:
[转]android 一直在最前面的浮动窗口效果 -
zee3.lin:
Sorry~~
When I build "call ...
Step by Step about How to Build libjingle 0.4
声明: 如果您要转载, 请事先征得本人的同意后方可并且请您附上原文链接. 本人保留一切权利. 多谢!
Google从FroYo版本后引入了C2DM (Cloud to Device Messaging)框架:
http://code.google.com/android/c2dm/index.html
Android Cloud to Device Messaging (C2DM) is a service that helps developers send data from servers to their applications on Android devices. The service provides a simple, lightweight mechanism that servers can use to tell mobile applications to contact the server directly, to fetch updated application or user data. The C2DM service handles all aspects of queueing of messages and delivery to the target application running on the target device.
这个C2DM框架实际上就是一种Push机制, 当服务器端有changes(creates/updates/deletes)时, 服务器端立刻会通过Push机制通知客户端, 然后客户端会通过Sync机制从服务器端获取server-side diffs, 同时也会把client-side diffs发送给服务器端. 通过Push机制, 用户可以及时获得服务器端的改动, 因此有更好的用户体验.
注:
1. Push机制的实现有多种, 比如通过SMS, 以及现在介绍的C2DM.
2. Android上的Sync机制这里不做过多介绍. 实际上对应下面介绍的内容Google是把Push机制和Sync机制一起使用的.
那么, C2DM的实现原理是什么呢? XMPP!!! 和Android GTalk Client的协议实现一样, 都是XMPP, 并且用的都是同一个XMPP框架, XMPP Stack的实现用的是开源的Smack. 其实, 在FroYo之前, Google的Push机制直接就是在XMPP上面, 只不过在引入了C2DM后, 变成Push机制在C2DM上面, 然后C2DM在XMPP上面了.
下面, 通过介绍Android上Google Contacts/Calendar如何利用C2DM实现Push机制来进行说明. 说的顺序可能比较乱, 大家慢慢理解, 并且其中的code只是用来帮助大家来进行理解.
1. 在AndroidManifest.xml上declare了一个broadcast receiver和一个对应的service用来接收C2DM发送的通知.
Google Sync是通过Atom Feed协议进行的. 这样当Server端有changes后, 会通过C2DM框架发送"com.google.android.c2dm.intent.RECEIVE" action给SubscribedFeedsBroadcastReceiver, 而SubscribedFeedsBroadcastReceiver在onReceive()方法启动SubscribedFeedsIntentService. 其可能的代码为:
关于"com.google.android.c2dm.intent.RECEIVE" action, 这是C2DM框架定义的标准action, 可以参考C2DM开发文档.
2. C2DM框架什么时候以及如何发送"com.google.android.c2dm.intent.RECEIVE" action.
这里用到的就是XMPP协议扩展. 这里扩展了XMPP的<message> packet, 在其中加入了自定义的elements. 当Google Server有changes后, 会通过XMPP发送<message>给Android上的XMPP client框架, XMPP client框架会解析<message> packet, 如果发现是关于Google Sync的<message> packet, 则发送"com.google.android.c2dm.intent.RECEIVE" action.
如何接收自定义的XMPP packets呢? 需要首先了解一下Smack的API, 这里不赘述.
2.1 类DataMessageManager
DataMessageManager是一个PacketListener, 当有特定的Packets到达时会调用它的processPacket()方法.
2.2 注册DataMessageManager这个PacketListener
注意这里的PacketTypeFilter用的是DataMessage, 表示DataMessage这样的XMPP packets才是需要处理的Packets.
2.3 类DataMessage
其中override了一个方法:
从这里可以发现, DataMessage对应的是类似下面的XMPP packets:
也就是说, 当Server端有changes需要客户端来sync的时候, 会发送类似与上面的消息给客户端, 这个消息会被DataMessageManager处理.
而在DataMessageManager的processPacket()方法中, 会再做如下判断:
这个code会认为category为"GSYNC_TICKLE"的XMPP packets才是有关Google Sync的, 并做相应转换.
3. SubscribedFeedsIntentService被启动, 会调用下面的API进行Sync, 后面涉及到的就是Android的Sync机制了, 如果有时间再解释.
大概的时序图为:
需要 smack 包是标准的开源方式,比如 androidpn
service一直开着还是需要的时候再开着, 都无所谓了,根据需要. Service各种情况都能满足的.
Google从FroYo版本后引入了C2DM (Cloud to Device Messaging)框架:
http://code.google.com/android/c2dm/index.html
Android Cloud to Device Messaging (C2DM) is a service that helps developers send data from servers to their applications on Android devices. The service provides a simple, lightweight mechanism that servers can use to tell mobile applications to contact the server directly, to fetch updated application or user data. The C2DM service handles all aspects of queueing of messages and delivery to the target application running on the target device.
这个C2DM框架实际上就是一种Push机制, 当服务器端有changes(creates/updates/deletes)时, 服务器端立刻会通过Push机制通知客户端, 然后客户端会通过Sync机制从服务器端获取server-side diffs, 同时也会把client-side diffs发送给服务器端. 通过Push机制, 用户可以及时获得服务器端的改动, 因此有更好的用户体验.
注:
1. Push机制的实现有多种, 比如通过SMS, 以及现在介绍的C2DM.
2. Android上的Sync机制这里不做过多介绍. 实际上对应下面介绍的内容Google是把Push机制和Sync机制一起使用的.
那么, C2DM的实现原理是什么呢? XMPP!!! 和Android GTalk Client的协议实现一样, 都是XMPP, 并且用的都是同一个XMPP框架, XMPP Stack的实现用的是开源的Smack. 其实, 在FroYo之前, Google的Push机制直接就是在XMPP上面, 只不过在引入了C2DM后, 变成Push机制在C2DM上面, 然后C2DM在XMPP上面了.
下面, 通过介绍Android上Google Contacts/Calendar如何利用C2DM实现Push机制来进行说明. 说的顺序可能比较乱, 大家慢慢理解, 并且其中的code只是用来帮助大家来进行理解.
1. 在AndroidManifest.xml上declare了一个broadcast receiver和一个对应的service用来接收C2DM发送的通知.
<receiver android:name=".subscribedfeeds.SubscribedFeedsBroadcastReceiver"> <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <category android:name="com.google.android.gsf.subscribedfeeds" /> </intent-filter> </receiver> <service android:name=".subscribedfeeds.SubscribedFeedsIntentService" />
Google Sync是通过Atom Feed协议进行的. 这样当Server端有changes后, 会通过C2DM框架发送"com.google.android.c2dm.intent.RECEIVE" action给SubscribedFeedsBroadcastReceiver, 而SubscribedFeedsBroadcastReceiver在onReceive()方法启动SubscribedFeedsIntentService. 其可能的代码为:
public class SubscribedFeedsBroadcastReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) { intent.setClass(context, SubscribedFeedsIntentService.class); context.startService(intent); } } }
关于"com.google.android.c2dm.intent.RECEIVE" action, 这是C2DM框架定义的标准action, 可以参考C2DM开发文档.
2. C2DM框架什么时候以及如何发送"com.google.android.c2dm.intent.RECEIVE" action.
这里用到的就是XMPP协议扩展. 这里扩展了XMPP的<message> packet, 在其中加入了自定义的elements. 当Google Server有changes后, 会通过XMPP发送<message>给Android上的XMPP client框架, XMPP client框架会解析<message> packet, 如果发现是关于Google Sync的<message> packet, 则发送"com.google.android.c2dm.intent.RECEIVE" action.
如何接收自定义的XMPP packets呢? 需要首先了解一下Smack的API, 这里不赘述.
2.1 类DataMessageManager
DataMessageManager是一个PacketListener, 当有特定的Packets到达时会调用它的processPacket()方法.
public class DataMessageManager implements PacketListener { ...... }
2.2 注册DataMessageManager这个PacketListener
PacketTypeFilter filter = new PacketTypeFilter(DataMessage.class); connection.addPacketListener(this, localPacketTypeFilter);
注意这里的PacketTypeFilter用的是DataMessage, 表示DataMessage这样的XMPP packets才是需要处理的Packets.
2.3 类DataMessage
public class DataMessage extends Message { ...... private ArrayList<AppData> mAppDataList; private String mCategory; private boolean mFromTrustedServer = 0; private String mPermission; private String mToken; ...... }
其中override了一个方法:
public String getExtensionsXML() { StringBuilder buf = new StringBuilder() buf.append("<data").append(" xmlns=\"")append("google:mobile:data").append("\""); if (getCategory() != null) buf.append(" category=\"").append(getCategory()).append("\""); if (getToken() != null) buf.append(" token=\"").append(getToken()).append("\""); if (getPermission() != null) buf.append(" permission=\"").append(getPermission()).append("\""); if (this.mFromTrustedServer) buf.append(" from-trusted-server=\"true\""); buf.append(">"); int size = getAppDataSize(); for (int i = 0; i < size; i++) { AppData appData = (AppData)this.mAppDataList.get(i); buf.append("<app-data key=\"").append(appData.getKey()).append("\" value=\"") .append(appData.getValue()).append("\" />"); } buf.append("</data>"; return buf.toString(); }
从这里可以发现, DataMessage对应的是类似下面的XMPP packets:
<message id="zUwxRf4-9" persistent_id="0:1295969265963580%e7a71353002ea1e0" from="google.com" type="headline"><data xmlns="google:mobile:data" category="GSYNC_TICKLE" token="cl_6" from-trusted-server="true"><app-data key="account" value="zhangsan.android@gmail.com" /></data></message>
也就是说, 当Server端有changes需要客户端来sync的时候, 会发送类似与上面的消息给客户端, 这个消息会被DataMessageManager处理.
而在DataMessageManager的processPacket()方法中, 会再做如下判断:
String category= dataMessage.getCategory(); if ("GSYNC_TICKLE".equals(str2)) category = "com.google.android.gsf.subscribedfeeds"; Intent intent = new Intent("com.google.android.c2dm.intent.RECEIVE"); intent.addCategory(category); ...... context.sendBroadcast(intent);
这个code会认为category为"GSYNC_TICKLE"的XMPP packets才是有关Google Sync的, 并做相应转换.
3. SubscribedFeedsIntentService被启动, 会调用下面的API进行Sync, 后面涉及到的就是Android的Sync机制了, 如果有时间再解释.
ContentResolver.requestSync(......);
大概的时序图为:
评论
12 楼
langdechuanshuo
2014-07-14
楼主你用什么工具画出那个图片的,我之前用过一段时间,在华为的时候,但是出来就不记得了。 一直想不起来。能告诉我吗!
11 楼
fajaven
2012-11-03
C2DM (新的名字叫 GCM)在国内实际上用不了,因为:
1)国内大部分 Android 手机都没有 Google帐号,所以用不了 Google服务
2)国内 Google服务不稳定。
所以,大家一般的选择是:自己用开源项目如 androidpn 搭建整套环境;另一种选择是使用第三方服务。
androidpn开源不成熟,问题还是挺多的。第三方服务方面,目前国内刚出来了一个,叫极光推送 (http://www.jpush.cn),它提供免费的消息推送服务,最快3分钟能够集成跑起来。
1)国内大部分 Android 手机都没有 Google帐号,所以用不了 Google服务
2)国内 Google服务不稳定。
所以,大家一般的选择是:自己用开源项目如 androidpn 搭建整套环境;另一种选择是使用第三方服务。
androidpn开源不成熟,问题还是挺多的。第三方服务方面,目前国内刚出来了一个,叫极光推送 (http://www.jpush.cn),它提供免费的消息推送服务,最快3分钟能够集成跑起来。
10 楼
fajaven
2012-11-03
JavaLaDeng 写道
这个必须要smack包吧..??
需要 smack 包是标准的开源方式,比如 androidpn
9 楼
bluceshang
2011-10-20
AdSFJLSDGH
8 楼
bluceshang
2011-10-20
7 楼
JavaLaDeng
2011-10-09
这个必须要smack包吧..??
6 楼
JavaLaDeng
2011-10-09
楼主可在,能否给一个demo?包括服务端的 772008232@qq.com 谢谢..
5 楼
dengsh2008
2011-02-25
我也想知道服务器是如何通知手机的,手机又不是一直在上网。
4 楼
ak121077313
2011-02-22
我只想知道"这样当Server端有changes后, 会通过C2DM框架发送"com.google.android.c2dm.intent.RECEIVE" action" service 是怎么发送给客户端的
3 楼
laiyangdeli
2011-02-10
zhs2472 写道
不用一直开着吧,貌似是接到命令才启动的Service
service一直开着还是需要的时候再开着, 都无所谓了,根据需要. Service各种情况都能满足的.
2 楼
zhs2472
2011-02-10
不用一直开着吧,貌似是接到命令才启动的Service
1 楼
yangrunfei
2011-02-10
,是不是这个服务客户端一直在开着呢,可以关闭不?
发表评论
-
[Android] 为Android安装BusyBox —— 完整的bash shell
2013-12-27 10:19 1412http://www.cnblogs.com/xiaowen ... -
Windows的adb shell中使用vi不乱码方法及AdbPutty
2013-12-27 10:17 7395http://www.veryhuo.com/down/ht ... -
AppMobi推出新XDK,可创建测试PhoneGap项目
2012-09-03 13:39 2531AppMobi今天发布了一个新的工具PhoneGap Mobi ... -
Sencha
2012-09-03 12:59 1140http://www.sencha.com/ Se ... -
jQuery Mobile学习
2012-09-01 12:33 1629使用Jquery Mobile设计Android通讯录 ... -
BackBone
2012-09-01 12:34 1220Backbone.js 是一种重量级javascript M ... -
jQTouch
2012-08-30 15:57 937A Zepto/jQuery plugin for mobil ... -
SwiFTP
2012-08-30 15:43 1243SwiFTP is a FTP server that run ... -
kWS
2012-08-30 15:41 1147kWS is a lightweight and fast W ... -
jQuery Mobile
2012-08-30 15:07 976http://jquerymobile.com/ -
PhoneGap
2012-08-30 15:07 994http://phonegap.com/ -
Android Button background image pressed/highlighted and disabled states without
2012-08-06 12:49 1624http://shikii.net/blog/android- ... -
[AndriodTips]Image, saved to sdcard, doesn't appear in Android's Gallery app
2012-08-04 16:15 1111http://stackoverflow.com/questi ... -
Voice detection for Android
2012-07-23 11:39 2294Here it is, my fist JAVA applic ... -
[AndroidTip]local reference table overflow (max=512)的错误解决
2012-07-22 22:56 5951JNI层coding经常会遇到ReferenceTable o ... -
[AndroidTip]EditText如何初始状态不获得焦点?
2012-07-22 15:35 1182最简单的办法是在EditText前面放置一个看不到的Linea ... -
[AndroidTip]android textview滚动条
2012-07-21 14:29 1258本来是想做一个显示文字信息的,当文字很多时View的高度不能超 ... -
Google公布Android 4.1完整功能
2012-07-16 09:48 3138http://www.android.com/about/je ... -
Android开发:使用AudioTrack播放PCM音频数据【附源码】
2012-07-13 15:20 20771http://www.linuxidc.com/Linux/2 ... -
Android上的行车记录仪
2012-07-11 22:31 1964MyCar Recorder DailyRoads
相关推荐
详细介绍了android平台的推送机制,原文是cnki上的,特意打包分享。
附件里有3个压缩包,分别是基于udp,xmpp,wmqtt实现push机制的客户端代码,可以参考http://tokudu.com/post/50024574938/how-to-implement-push-notifications-for-android,哈哈,不过是英文的。
使用android push notification service 实现即时通知
Android push notification(即androidpn) 服务端源代码 非bin文件,而是源代码!
因此,WAP PUSH实现了短信和WAP业务的结合,节省了您寻找业务的时间,方便您直接找到并使用自己喜 欢的业务。PUSH信息无论是否被用户打开,都会保留在手机 的"推入收件箱"内,用户可以重复打开。 wap push 的意思...
Android XMPP PUSH 推送源代码,客户端、服务端实现Android推送,服务端使用tomcat服务器
android 开发 push 短信协议解析,push短信头,sl,si,co三种push短信的协议解析。用来支持android中mms不支持push短信的缺陷。开发必备
Android Push 服务器和客户端。具体使用方法可参照:http://www.cnblogs.com/hanyonglu/archive/2012/03/16/2399655.html
水晶报表 pull push 源代码
To start using it, you need to have set up the Push Server. With the Push Server OK, open the file Config.java and change the addresses of your server and the GCM Sender ID: public static class ...
NULL 博文链接:https://seya.iteye.com/blog/903137
gradle-mvn-push See this blog post for more context on this 'library': http://chris.banes.me/2013/08/27/pushing-aars-to-maven-central/. Usage 1. Have a working Gradle build This is upto you. 2. Update...
一般情况下,使用较标准的Google的android系统,拦截比较成功(例如:摩托罗拉)。 如果手机厂商做了较大的改动,拦截可能会有问题。 例如:联想的乐Phone,魅族M9,等拦截不好。会出现短信进入收件箱,才删除,或者...
Android第三方PUSH-SDK总结。包括小米PUSH
接下来说说XMPP在android客户端上的应用。分两部分:服务端搭建和客户端实现。 服务端搭建: 点击bin目录下得run.bat,直接搭好服务,在浏览器上输入 http://127.0.0.1:7070 ,可以修改配置在conf/config....
自己做的一个android Push功能
NULL 博文链接:https://fanfq.iteye.com/blog/1405385
google 给出的 android push 开发指导。 (Building Push Applications for Android)
XMPP(可扩展通讯和表示协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线探测。这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息。
Android Push it单机版事件管理APP是一款个人独立开发的免费android应用,主要应用于日常事务管理,期望能够帮助个人和团队更好地把握时间,让工作和生活更加井井有条。 由于能力和精力有限,完整版的应用可能实现...