- 浏览: 1481525 次
- 性别:
- 来自: 南京
文章分类
- 全部博客 (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
[原创]使用Smack库实现Google Talk XMPP Extensions - Gmail Notifications (含完整的实现代码以及例子)
- 博客分类:
- XMPP
注意: 这里有本人所写的完整的代码, 所以如果要转载, 请征得本人同意然后加上原文出处; 如果使用代码, 只需要加上本文的Link就可以了.
Gmail Notifications的是Google Talk XMPP Extensions其中之一, 它的用途是Gmail服务器有新邮件的时候, 会通过XMPP协议Push给客户端, 然后客户端可以通过XMPP协议去查询新邮件的信息, 包括新邮件的标题,摘要,发件人邮件地址等.
这个功能其实GTalk客户端已经有了, 但既然已经有了标准的文档, 何不妨把这个功能也加到自己的IM客户端上呢. 当然这个Extension只能用于GTalk服务器.
关于这个Extension的介绍, 请看Google的文档:
http://code.google.com/intl/zh-CN/apis/talk/jep_extensions/gmail.html
下面就直接上传代码, 代码不介绍了, 对照文档应该很好理解的, 其实也很简单.
例子程序
我工作的方向并不是XMPP等,只是兴趣。现在工作比较忙,已经好久没研究这个了。
我是按照Smack的style来实现这个extension的.
Gmail Notifications的是Google Talk XMPP Extensions其中之一, 它的用途是Gmail服务器有新邮件的时候, 会通过XMPP协议Push给客户端, 然后客户端可以通过XMPP协议去查询新邮件的信息, 包括新邮件的标题,摘要,发件人邮件地址等.
这个功能其实GTalk客户端已经有了, 但既然已经有了标准的文档, 何不妨把这个功能也加到自己的IM客户端上呢. 当然这个Extension只能用于GTalk服务器.
关于这个Extension的介绍, 请看Google的文档:
http://code.google.com/intl/zh-CN/apis/talk/jep_extensions/gmail.html
下面就直接上传代码, 代码不介绍了, 对照文档应该很好理解的, 其实也很简单.
package com.hj.smack.demo.gmailnotif; import org.jivesoftware.smack.packet.IQ; public class EmailNotification extends IQ { @Override public String getChildElementXML() { StringBuilder buf = new StringBuilder(); buf.append("<new-mail xmlns=\"").append("google:mail:notify").append("\""); buf.append("/>"); return buf.toString(); } }
package com.hj.smack.demo.gmailnotif; import org.jivesoftware.smack.packet.IQ; public class EmailQueryRequest extends IQ { private Long newerThanTime; private Long newThanTid; private String query; @Override public String getChildElementXML() { StringBuilder buf = new StringBuilder(); buf.append("<query xmlns=\"").append("google:mail:notify").append("\""); if (newerThanTime != null) { buf.append(" newer-than-time=\"").append(newerThanTime).append("\""); } if (newThanTid != null) { buf.append(" newer-than-tid=\"").append(newThanTid).append("\""); } if (query != null) { buf.append(" q=\"").append(query).append("\""); } buf.append("/>"); return buf.toString(); } public void setNewerThanTime(Long newerThanTime) { this.newerThanTime = newerThanTime; } public Long getNewerThanTime() { return newerThanTime; } public void setNewThanTid(Long newThanTid) { this.newThanTid = newThanTid; } public Long getNewThanTid() { return newThanTid; } public void setQuery(String query) { this.query = query; } public String getQuery() { return query; } }
package com.hj.smack.demo.gmailnotif; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import org.jivesoftware.smack.packet.IQ; public class EmailQueryResponse extends IQ { private Mailbox mailbox; @Override public String getChildElementXML() { StringBuilder buf = new StringBuilder(); if (mailbox != null) { buf.append(mailbox.toXML()); } return buf.toString(); } public Mailbox getMailbox() { return mailbox; } public void setMailbox(Mailbox mailbox) { this.mailbox = mailbox; } public static class Mailbox { private Long resultTime; private Integer totalMatched; private Boolean totalEstimated; private String url; private List<MailThreadInfo> mailThreadInfos = new CopyOnWriteArrayList<MailThreadInfo>(); public String toXML() { StringBuilder buf = new StringBuilder(); buf.append("<mailbox xmlns=\"").append("google:mail:notify").append("\""); buf.append(" result-time=\"").append(resultTime).append("\""); buf.append(" total-matched=\"").append(totalMatched).append("\""); if (totalEstimated != null) { if (totalEstimated) { buf.append(" total-estimate=\"").append("1").append("\""); } else { buf.append(" total-estimate=\"").append("0").append("\""); } } buf.append(">"); synchronized (mailThreadInfos) { for (MailThreadInfo mailThreadInfo : mailThreadInfos) { buf.append(mailThreadInfo.toXML()); } } buf.append("</mailbox>"); return buf.toString(); } public void addMailThreadInfo(MailThreadInfo mailThreadInfo) { synchronized (mailThreadInfos) { mailThreadInfos.add(mailThreadInfo); } } public Iterator<MailThreadInfo> getMailThreadInfos() { synchronized (mailThreadInfos) { return Collections.unmodifiableList(mailThreadInfos).iterator(); } } public Long getResultTime() { return resultTime; } public void setResultTime(Long resultTime) { this.resultTime = resultTime; } public Integer getTotalMatched() { return totalMatched; } public void setTotalMatched(Integer totalMatched) { this.totalMatched = totalMatched; } public Boolean getTotalEstimated() { return totalEstimated; } public void setTotalEstimated(Boolean totalEstimated) { this.totalEstimated = totalEstimated; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public static class MailThreadInfo { private Long tid; private Integer participation; private Integer messages; private Long date; private String url; private String labels; private String subject; private String snippet; private List<Sender> senders = new CopyOnWriteArrayList<Sender>(); public String toXML() { StringBuilder buf = new StringBuilder(); buf.append("<mail-thread-info tid=\"").append(tid).append("\""); buf.append(" participation=\"").append(participation).append("\""); buf.append(" date=\"").append(date).append("\""); buf.append(" url=\"").append(url).append("\""); buf.append(">"); buf.append("<senders>"); synchronized (senders) { for (Sender sender : senders) { buf.append(sender.toXML()); } } buf.append("</senders>"); buf.append("<labels>").append(labels).append("</labels>"); buf.append("<subject>").append(subject).append("</subject>"); buf.append("<snippet>").append(snippet).append("</snippet>"); buf.append("</mail-thread-info>"); return buf.toString(); } public void addSender(Sender sender) { synchronized (senders) { senders.add(sender); } } public Iterator<Sender> getSenders() { synchronized (senders) { return Collections.unmodifiableList(senders).iterator(); } } public String getLabels() { return labels; } public void setLabels(String labels) { this.labels = labels; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getSnippet() { return snippet; } public void setSnippet(String snippet) { this.snippet = snippet; } public Long getTid() { return tid; } public void setTid(Long tid) { this.tid = tid; } public Integer getParticipation() { return participation; } public void setParticipation(Integer participation) { this.participation = participation; } public Integer getMessages() { return messages; } public void setMessages(Integer messages) { this.messages = messages; } public Long getDate() { return date; } public void setDate(Long date) { this.date = date; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public static class Sender { private String name; private String address; private Boolean originator; private Boolean unread; public String toXML() { StringBuilder buf = new StringBuilder(); buf.append("<sender name=\"").append(name).append("\""); buf.append(" address=\"").append(address).append("\""); if (originator != null) { if (originator) { buf.append(" originator=\"").append("1").append("\""); } else { buf.append(" originator=\"").append("0").append("\""); } } if (unread != null) { if (unread) { buf.append(" unread=\"").append("1").append("\""); } else { buf.append(" unread=\"").append("0").append("\""); } } buf.append("/>"); return buf.toString(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public Boolean getOriginator() { return originator; } public void setOriginator(Boolean originator) { this.originator = originator; } public Boolean getUnread() { return unread; } public void setUnread(Boolean unread) { this.unread = unread; } } } } }
package com.hj.smack.demo.gmailnotif; import org.jivesoftware.smack.PacketCollector; import org.jivesoftware.smack.PacketListener; import org.jivesoftware.smack.SmackConfiguration; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.filter.PacketIDFilter; import org.jivesoftware.smack.filter.PacketTypeFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.util.StringUtils; public class GmailNotificationManager { private XMPPConnection connection; private GmailNotificationListener listener; public GmailNotificationManager(XMPPConnection connection) { this.connection = connection; init(); } private void init() { // Listen for new-email notification PacketFilter packetFilter = new PacketTypeFilter(EmailNotification.class); PacketListener packetListener = new PacketListener() { public void processPacket(Packet packet) { EmailNotification notif = (EmailNotification)packet; // Notify registered listener if (listener != null) { listener.hasNewEmail(); } // Should respond to the server IQ req = new IQ() { @Override public String getChildElementXML() { return null; } }; req.setType(IQ.Type.RESULT); req.setFrom(notif.getTo()); req.setTo(notif.getFrom()); req.setPacketID(notif.getPacketID()); connection.sendPacket(req); } }; connection.addPacketListener(packetListener, packetFilter); } public void setGmailNotificationListener(GmailNotificationListener listener) { this.listener = listener; } public EmailQueryResponse.Mailbox checkMailbox(String jid) throws XMPPException { EmailQueryRequest req = new EmailQueryRequest(); req.setType(IQ.Type.GET); String bare = StringUtils.parseBareAddress(jid); req.setFrom(jid); req.setTo(bare); // Create a packet collector to listen for a response. PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(req.getPacketID())); connection.sendPacket(req); // Wait up to 5 seconds for a result. IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); // Stop queuing results collector.cancel(); if (result == null) { throw new XMPPException("No response from the server."); } if (result.getType() == IQ.Type.ERROR) { throw new XMPPException(result.getError()); } return ((EmailQueryResponse) result).getMailbox(); } public static interface GmailNotificationListener { public void hasNewEmail(); } }
package com.hj.smack.demo.gmailnotif; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.provider.IQProvider; import org.xmlpull.v1.XmlPullParser; public class GmailNotificationProvider implements IQProvider { @Override public IQ parseIQ(XmlPullParser parser) throws Exception { EmailQueryResponse gmailQueryResp = null; EmailNotification gmailNotif = null; boolean done = false; EmailQueryResponse.Mailbox mailbox = null; EmailQueryResponse.Mailbox.MailThreadInfo mailThreadInfo = null; EmailQueryResponse.Mailbox.MailThreadInfo.Sender sender = null; // Cache the text String cachedText = ""; // Mailbox attributes String resultTime = ""; String totalMatched = ""; String totalEstimated = null; String mailboxUrl = ""; // MailThreadInfo attributes String tid = ""; String participation = ""; String messages = ""; String date = ""; String mailThreadInfoUrl = ""; String labels = ""; String subject = ""; String snippet = ""; // Sender attributes String name = ""; String address = ""; String originator = null; String unread = null; if (parser.getName().equals("new-mail")) { gmailNotif = new EmailNotification(); } else { // Initialize the variables from the parsed XML resultTime = parser.getAttributeValue("", "result-time"); totalMatched = parser.getAttributeValue("", "total-matched"); totalEstimated = parser.getAttributeValue("", "total-estimate"); mailboxUrl = parser.getAttributeValue("", "mailboxUrl"); // Create a new Mailbox and add it to the GmailNotifications gmailQueryResp = new EmailQueryResponse(); mailbox = new EmailQueryResponse.Mailbox(); mailbox.setResultTime(Long.parseLong(resultTime)); mailbox.setTotalMatched(Integer.parseInt(totalMatched)); mailbox.setTotalEstimated(totalEstimated != null ? Boolean.parseBoolean(totalEstimated) : null); mailbox.setUrl(mailboxUrl); gmailQueryResp.setMailbox(mailbox); } while (!done) { int eventType = parser.next(); if (eventType == XmlPullParser.START_TAG) { if (parser.getName().equals("mail-thread-info")) { // Initialize the variables from the parsed XML tid = parser.getAttributeValue("", "tid"); participation = parser.getAttributeValue("", "participation"); messages = parser.getAttributeValue("", "messages"); date = parser.getAttributeValue("", "date"); mailThreadInfoUrl = parser.getAttributeValue("", "url"); // Create a new MailThreadInfo and add it to the Mailbox mailThreadInfo = new EmailQueryResponse.Mailbox.MailThreadInfo(); mailThreadInfo.setTid(Long.parseLong(tid)); mailThreadInfo.setParticipation(Integer.parseInt(participation)); mailThreadInfo.setMessages(Integer.parseInt(messages)); mailThreadInfo.setDate(Long.parseLong(date)); mailThreadInfo.setUrl(mailThreadInfoUrl); mailbox.addMailThreadInfo(mailThreadInfo); } else if (parser.getName().equals("sender")) { // Initialize the variables from the parsed XML name = parser.getAttributeValue("", "name"); address = parser.getAttributeValue("", "address"); originator = parser.getAttributeValue("", "originator"); unread = parser.getAttributeValue("", "unread"); // Create a new Sender and add it to the MailThreadInfo sender = new EmailQueryResponse.Mailbox.MailThreadInfo.Sender(); sender.setName(name); sender.setAddress(address); sender.setOriginator(originator != null ? Boolean.parseBoolean(totalEstimated) : null); sender.setUnread(unread != null ? Boolean.parseBoolean(unread) : null); mailThreadInfo.addSender(sender); } } else if (eventType == XmlPullParser.TEXT) { cachedText = parser.getText(); } else if (eventType == XmlPullParser.END_TAG) { if (parser.getName().equals("new-mail") || parser.getName().equals("mailbox")) { done = true; } else if (parser.getName().equals("mail-thread-info")) { } else if (parser.getName().equals("sender")) { } else if (parser.getName().equals("labels")) { labels = cachedText; mailThreadInfo.setLabels(labels); } else if (parser.getName().equals("subject")) { subject = cachedText; mailThreadInfo.setSubject(subject); } else if (parser.getName().equals("snippet")) { snippet = cachedText; mailThreadInfo.setSnippet(snippet); } } } if (gmailNotif != null) { return gmailNotif; } else { return gmailQueryResp; } } }
例子程序
package com.hj.smack.demo; import org.jivesoftware.smack.ConnectionConfiguration; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.provider.ProviderManager; import com.hj.smack.demo.gmailnotif.EmailQueryResponse; import com.hj.smack.demo.gmailnotif.GmailNotificationManager; import com.hj.smack.demo.gmailnotif.GmailNotificationProvider; import com.hj.smack.demo.gmailnotif.GmailNotificationManager.GmailNotificationListener; public class GmailNotifTest { /** * @param args */ public static void main(String[] args) { XMPPConnection.DEBUG_ENABLED = false; ProviderManager providerManager = ProviderManager.getInstance(); providerManager.addIQProvider("mailbox", "google:mail:notify", new GmailNotificationProvider()); providerManager.addIQProvider("new-mail", "google:mail:notify", new GmailNotificationProvider()); ConnectionConfiguration config = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com"); config.setCompressionEnabled(true); config.setSASLAuthenticationEnabled(true); XMPPConnection connection = new XMPPConnection(config); try { connection.connect(); connection.login("xxxxxx@gmail.com", "*******"); demoGmailNotif(connection); Thread.sleep(500000); } catch (Exception e) { e.printStackTrace(); } finally { connection.disconnect(); } } public static void demoGmailNotif(XMPPConnection connection) { String my = connection.getUser(); GmailNotificationManager m = new GmailNotificationManager(connection); m.setGmailNotificationListener(new MyGmailNotificationListener(connection)); try { EmailQueryResponse.Mailbox mailbox = m.checkMailbox(my); System.out.println(mailbox.toXML()); } catch (XMPPException e) { e.printStackTrace(); } } private static class MyGmailNotificationListener implements GmailNotificationListener { private XMPPConnection connection; public MyGmailNotificationListener(XMPPConnection connection) { this.connection = connection; } @Override public void hasNewEmail() { System.out.println("You have new emails in your gmail inbox!"); String my = connection.getUser(); GmailNotificationManager m = new GmailNotificationManager(connection); EmailQueryResponse.Mailbox mailbox; try { mailbox = m.checkMailbox(my); System.out.println(mailbox.toXML()); } catch (XMPPException e) { e.printStackTrace(); } } } }
评论
4 楼
laiyangdeli
2011-08-15
bluky999 写道
浏览了一下LZ的日志,尤其是XMPP分类下的,看来对XMPP/jabber openfire ejabberd ,spark psi 等都了解了一遍; 猜想LZ当时也是在参与什么IM系统构建相关的项目吧?!
想问下,LZ最后有无开发相关的产品出来? 比如目前流行的多人语音聊天的移动app啊之类的? 如果有的话,那么服务端的技术选型和技术架构是怎么样的?可否简单做介绍?我最近你也在关注这个方向
想问下,LZ最后有无开发相关的产品出来? 比如目前流行的多人语音聊天的移动app啊之类的? 如果有的话,那么服务端的技术选型和技术架构是怎么样的?可否简单做介绍?我最近你也在关注这个方向
我工作的方向并不是XMPP等,只是兴趣。现在工作比较忙,已经好久没研究这个了。
3 楼
bluky999
2011-08-15
浏览了一下LZ的日志,尤其是XMPP分类下的,看来对XMPP/jabber openfire ejabberd ,spark psi 等都了解了一遍; 猜想LZ当时也是在参与什么IM系统构建相关的项目吧?!
想问下,LZ最后有无开发相关的产品出来? 比如目前流行的多人语音聊天的移动app啊之类的? 如果有的话,那么服务端的技术选型和技术架构是怎么样的?可否简单做介绍?我最近你也在关注这个方向
想问下,LZ最后有无开发相关的产品出来? 比如目前流行的多人语音聊天的移动app啊之类的? 如果有的话,那么服务端的技术选型和技术架构是怎么样的?可否简单做介绍?我最近你也在关注这个方向
2 楼
laiyangdeli
2011-02-22
smildlzj 写道
不错,恰巧前段时间也实现了...不过没你那么长..也没你那么完善
我是按照Smack的style来实现这个extension的.
1 楼
smildlzj
2011-02-21
不错,恰巧前段时间也实现了...不过没你那么长..也没你那么完善
发表评论
-
Android Push Notification
2012-03-22 16:09 1229http://sourceforge.net/projects ... -
使用 XMPP 构建一个基于 web 的通知工具
2011-03-01 10:32 1532http://www.ibm.com/developerwor ... -
Smack 3.2.0 Beta has been released
2011-02-27 20:10 1315大约2个星期前, Smack发布3.2.0 Beta版. 距离 ... -
Jingle XMPP stanza对应的XML schema
2011-02-25 20:22 2875一个典型的Jingle XMPP stanza: <i ... -
GMail add 'voice and video chat' support
2011-02-18 13:32 1921GMail增加对视频聊天的 ... -
Ident协议
2011-02-08 18:06 3258为何要安装 identd ? 曾听过有人形容 id ... -
贴个XMPP logs看看Pidgin是如何传输文件的
2011-02-07 20:40 2566zhangsan给lisi发送01.jpg文件. (20:2 ... -
晕, Pidgin在Windows上不支持Voice&Viedo
2011-02-07 20:03 1554从http://pidgin.im/上下载了最新版本2.7.9 ... -
[转]XMPP协议之Socket5 Bytestream文件传输
2011-02-06 21:55 5756From: http://bbs.7boo.com.cn/th ... -
GTALK的运行参数
2011-02-06 21:51 1806/nomutex 同时打开多个Talk。 /forcestar ... -
Smack Jingle库所用的JSTUN库存在的bug
2011-02-06 19:52 4453运行Smack Jingle demo时(http://fis ... -
Google Talk Call Signaling
2011-02-05 22:53 1369http://code.google.com/intl/zh- ... -
几种XMPP客户端实现Jingle语音聊天的总结
2011-02-05 20:48 30812XMPP客户端除了最基本的发送/接收消息,显示好友列表等功能外 ... -
关于ejabberd在Windows 7无法启动
2011-02-04 22:13 2233用了Openfire作为XMPP Server后,突然想试试e ... -
XMPP Client
2011-02-04 20:58 1490Spark http://www.igniterealtime ... -
XMPP Server
2011-02-04 20:50 1684Openfire http://www.igniterealt ... -
XEP-0065: SOCKS5 Bytestreams
2011-02-04 15:24 2936SOCKS5 Bytestreams ("S ... -
XEP-0047: In-Band Bytestreams
2011-02-04 14:34 2145In-Band Bytestreams (IBB) http: ...
相关推荐
android下的XMPP对应smack-4.2.1,实现登录,注册,发单聊,加聊天室,发群聊等简单功能
smack-im-4.2.2.jar smack-tcp-4.2.2.jar smack-extensions-4.2.2.jar smack-core-4.2.2.jar smack-android-extensions-4.2.2.jar jxmpp-jid-0.6.0.jar jxmpp-core-0.6.0.jar jxmpp-util-cache-0.6.0.jar等jar包
smack4.1.5 实现xmpp 所需要的所有jar,包括jxmpp-core-0.4.1,jxmpp-util-cache-0.4.1,minidns-0.1.3
android下的XMPP对应smack-4.2.1,实现登录,注册,发单聊,加聊天室,发群聊等简单功能
fast-video-view.zip,用于Android的基于TextureView的VideoView实现。用于Android的基于TextureView的VideoView实现。
xmpp客户端协议实现源代码
sqlbuilder.zip,一个用于构建和执行SQL Stasks.SQL Builder库的轻量级库
基于XMPP 协议的Java聊天示例程序,已在本人机子上测试成功!
smack4.1.0的依赖包minidns.jar。可用于smack4.1.3,亲测可用!
jxmpp-core-0.5.0-alpha7 jxmpp-util-cache-0.5.0-alpha7 smack-android-4.1.6 smack-core-4.1.6 smack-extensions-4.1.6 smack-im-4.1.6 smack-sasl-provided-4.1.6 smack-tcp-4.1.6
smack用于android移动端的开发,可以结合openfire使用,进行im通信
smack与asmack的区别(包名对比解析)
peon.zip,一种牡丹,它在后台执行你想扔给它的任何体力劳动任务;一种爪哇牡丹,它在后台执行你想扔给它的任何体力劳动任务。
java本地可用,连接、登陆、接收消息
xmpp协议,使用smack实现的 博文见http://blog.csdn.net/wklken/article/details/6460075
关于Smack编程库,前面我们提到,它是面向Java端的api,主要在PC上使用,利用它我们可以向openfire服务器注册用户,发送消息,并且可以通过监听器获得此用户的应答消息,以及构建聊天室,分组,个人通讯录等等。
xmpp smack jar 库 ,用于开发
实现xmpp 所需要的所有jar,包括jxmpp-core-0.4.1,jxmpp-util-cache-0.4.1
安卓xmpp聊天之文件传输
xmpp-muc-android 使用 Smack 的 XMPP MUC androud 客户端示例