I was using Smack API in my application JabberTwitterBridge. It is jabber API. I use it to connect to server like Google Talk.
But when I was connected to Google, I couldn’t update my status by sending a standard Presence packet. I search a long time before finding why. In fact, google used a feature to manage old status list. It is described on this page :
http://code.google.com/apis/talk/jep_extensions/shared_status.html
Google give important information on this page, for example :
The server rewrites and sends out the following value to all subscribed contacts and other instances. Note that the
<status>value used is the current shared value, not the value just sent by the<presence>stanza.
That’s mean with must use a special command, we found it on this page to
<iq type='set' to='romeo@gmail.com/orchard' id='ss-2'> <query xmlns='google:shared-status' version='2'> <status>Juliet's here</status> <show>default</status> <status-list show='default'> <status>Juliet's here</status> <status>Pining away</status> <status>Wherefor indeed</status> <status>Thinking about the sun</status> </status-list> <status-list show='dnd'> <status>Chilling with Mercutio</status> <status>Visiting the monk</status> </status-list> <invisible value='false'/> </query> </iq> |
In fact, Smack give a class call IQ that it is easy to evolve. Just make a new class which herit this IQ class. Then just implement the function writing the query tag into xml. Easy isin’t it.
package com.cba.jabberTwitterBridge.arch.com.jabber; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Presence; public class PresenceGoogle extends IQ { protected String userName; protected String status; protected boolean visible; protected Presence.Mode mode; /** * Override toXML in the case of mode is away * Because Google Talk interprets the 'away' * status as idle, and idleness is a * per-connection property, you cannot set an * 'away' status using this method. To set an * idle status message, send a * standard <presence> stanza. : */ @Override public String toXML() { if ( mode.equals(Presence.Mode.away) ) { Presence p = new Presence(Presence.Type.available); p.setMode(mode); p.setStatus(status); return p.toXML(); } else { return super.toXML(); } } /** * Constructor * @param userName the userName * @param status the new status * @param visible the visible state > false to be invisble */ public PresenceGoogle(String userName, String status, boolean visible) { super(); this.userName = userName; this.status = status; this.visible = visible; setType(IQ.Type.SET); // I am not sure this code must be test // in case of a domain different of gmail.com // using gmail.com... if( userName.indexOf("@") != -1) { setTo(userName + ""); } else { setTo(userName + "@gmail.com"); } mode = Presence.Mode.available; } /** * Constructor * @param userName the userName * @param status the new status */ public PresenceGoogle(String userName, String status) { this(userName,status,false); } /** * Return the XML of changing status * for google * according * http://code.google.com/apis/talk/jep_extensions/shared_status.html */ @Override public String getChildElementXML() { StringBuilder buf = new StringBuilder(); // set query header buf.append("<query xmlns='google:shared-status' version='2'>"); // set status buf.append("<status>").append(status).append("</status>"); // set mode buf.append("<show>").append(mode).append("</show>"); // set invisible mode if ( visible ) { buf.append("<invisible value='false'/>"); } else { buf.append("<invisible value='true'/>"); } // close query buf.append("</query>"); return buf.toString(); } public Presence.Mode getMode() { return mode; } public void setMode(Presence.Mode mode) { this.mode = mode; } } |
If you have any question let me a comment.







Nice info.
But what about the part in the getChildElementXML() code??
November 25th, 2008