浏览 9689 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-02-07
最后修改:2011-02-09
注意: 这里有本人所写的完整的代码, 所以如果要转载, 请征得本人同意然后加上原文出处; 如果使用代码, 只需要加上本文的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 下面就直接上传代码, 代码不介绍了, 对照文档应该很好理解的, 其实也很简单. 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(); } } } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-02-21
不错,恰巧前段时间也实现了...不过没你那么长..也没你那么完善
|
|
返回顶楼 | |
发表时间:2011-02-22
smildlzj 写道 不错,恰巧前段时间也实现了...不过没你那么长..也没你那么完善
我是按照Smack的style来实现这个extension的. |
|
返回顶楼 | |