XMPP and Presence
In this blog post, we will be looking at Cius compatibility with Webex and CUP (Cisco Unified Presence) using the open protocol XMPP. XMPP stands for Extensible Messaging and Presence Protocol. It can be used to access contact lists, see presences, and to send and receive messages in Webex, CUP, and any other compatible XMPP service. In this particular post, I will detail how to use a 3rd-party XMPP library to create an Android application that shows the presence status of a person's contact list.
First, you will need to download a 3rd-party library, in Java, obviously, to take advantage of the XMPP interfaces. The one that will be used in this post is called Smack, designed by Ignite Realtime. Any XMPP library can be used, you could even right your own if you so choose, but for the remainder of this post, any references to code using XMPP will be directly related to the Smack API. One of the first things that you will need to do in your application is collect sign on credentials. There are 5 main things that you will need to collect from the user: username, password, server, port, and service name. These are all pretty self explanatory. The port is usually 5222, server is the location of the XMPP server, and service is what comes after the '@' in the username, examples being "@gmail.com", "@yahoo.com", etc. The following code is an example of a function that would take in the previous variables and create a connection to an XMPP server:
2 String server, String port, String service) throws XMPPException
3 {
4 ConnectionConfiguration config =
5 new ConnectionConfiguration(server, port, service);
6 config.setSecurityMode(SecurityMode.enabled);
7 config.setSASLAuthenticationEnabled(true);
8
9 XMPPConnection connection = new XMPPConnection(config);
10 connection.connect();
11 connection.login(userName, password);
12 return connection;
13 }
One bit of warning: If you receive SASL authentication errors, one possible reason may be the format of your username. Try the username with and without the service name on the end. Some servers only authenticate with the '@' part on the end of the username, some only do it without, so experiment with that if this issue arises for you.
The next step would be to get a list, or group, of contacts to display presence for. Using XMPP, one can display a complete list of one's contacts, or can show a single group of contacts, assuming the user has groups configured in his/her account. The following is code to return a group, by name:
2 String groupName)
3 {
4 ArrayList<RosterEntry> group=new ArrayList<RosterEntry>();
5 Collection<RosterEntry> entries =
6 connection.getRoster().getGroup(groupName).getEntries();
7 for(RosterEntry r:entries)
8 {
9 group.add(r);
10 }
11 return group;
12 }
The other option, if you don't care about groups, or the user doesn't have any setup, and want to just allow the user to view all his contacts at once. This is how to do that:
2 {
3 ArrayList<RosterEntry> group=new ArrayList<RosterEntry>();
4 Collection<RosterEntry> entries = connection.getRoster().getEntries();
5 for(RosterEntry r:entries)
6 {
7 group.add(r);
8 }
9 return group;
10 }
Finally a couple other things that you might want to know how to do. To specifically get the presence of a person on that list, you would use this code:
2 XMPPConnection connection, RosterEntry re)
3 {
4 org.jivesoftware.smack.packet.Presence presence =
5 connection.getRoster().getPresence(re.getUser().toString());
6 return presence;
7 }
And finally, if you want your application to update roster changes, such as new members being added to a contact list, members being deleted, and their presences changing, you need to implement a RosterListener (and its default methods) and add it to the connection's roster. Here is sample code to show this listener being added in the main class:
This will add a RosterListener (called RosterUpdater) to the connection's overall Roster and give it a Handler (in this case one called mHandler) to work with when some part of the Roster is updated or otherwise changed. These Handlers are necessary in Android because in order for this class to actually make any changes to the main class' variables, a Handler is the best, most "Android" way of sending data back and forth, especially between secondary classes and the main UI class. Creating the Handler can be done in whatever way is necessary to make your application work.