powered by Jive Software

Brief Tutorial on IQ Providers

After spending quite some time getting IQ Providers up and running with SMACK API I would like to describe it briefly. Since I also read quite a few questions and answers at forums like this one I would like to give something back. Maybe it helps someone else.

Problem which was to be solved:

I wanted to implement a bot which receives custom IQ Stanzas and puts the data into a database.

On the other end was a client which was sending the IQ Stanza.

Both sides (the client as well as the bot) are developed using the SMACK API

Here is how I did it:

1: Client: Sending the IQ Stanza

First create a new class which extends the IQ class und overwrites the getChildElementXML:

public class CustomIQ extends IQ {

float myData;

public String getChildElementXML() {

                           String request = "<query xmlns='myxmlns’>"

                                                           + "< myData >"+ myData + "</ myData >"

                                                           + "</query>";

                           return request;



Init your IQ and send it:

CustomIQ myIQ = new CustomIQ();

myIQ. setType(IQ.Type.GET); //or use instead GET

myIQ.setTo(“jid@bot”); //replace it with the receiver jid

connection.sendPacket(myIQ); //connection is an instance of XMMPConnection

  1. Setup the Bot

First you have to set up a so called IQProvider. An IQProvider transforms the data of the XML child data into an IQ Object and returns it. It does not perform any actions on the data except for setting up the values of an IQ Object. This IQ can later on be processed by a PacketListener or PacketCollector.

So let us set up the Provider:

public class customIQProvider implements IQProvider {

CustomIQ myIQ = new CustomIQ();

int eventType = parser.next();

                           while ( eventType == XmlPullParser.START_TAG) {

                                           name = parser.getName();

                                           switch (parser.getEventType()){

                                           case XmlPullParser.START_TAG:


                                                                           if (name.equalsIgnoreCase("myDATA")){




                           return myIQ;



Once the provider is implemented, you have to add it to the connection:

ProviderManager.getInstance().addIQProvider(“query”, " myxmlns ", new customIQProvider());

So now all the custom IQ Stanzas which have a “query” and the myxmlns namespace are handled to the provider. The provider the parsese the XML and sets the values of the IQ Classes.

So now all which still has to be done is to implement a PacketListener or PacketCollector to process the IQ. Here is my suggestion:

First set up a filter which returns “true” on all the Custom IQ Stanzas:

public class myIQFilter implements PacketFilter{

            public myIQFilter() {



            public boolean accept(Packet packet) {

                           boolean CustomIQReceived = false;

                           if (packet instanceof CustomIQ){

                                           CustomIQReceived = true;


                           return CustomIQReceived;



Now set up a PacketListener:

public class myIQListener implements PacketListener{

CustomIQ reply = new CustomIQ();

XMPPConnection connection;

public myIQListener(XMPPConnection con) {

                           connection = con;


public void processPacket(Packet packet) {

                            //Do all the processing here like accessing a database and so on..

                            //Now return the result IQ..

                           reply. setType(IQ.Type.RESULT)







And now all you still have to do is to register the PacketListener (main thread):

connection.addPacketListener((new myIQListener(connection)),new myIQFilter()) ; //connection is an instance of the XMPPConnection.

I hope this helps someone and maybe helps to save some time. I would also appreciate suggestion on possibilisites to find a better way…

Good tutorial. +1

Just one point: XML elements are (more or less) case sensitive. I recommend not to use equalsIgnoreCase when matching the name. Instead you should go with either “mydata” or “myData”.

Oh, and are you able to create this post as Document under http://community.igniterealtime.org/community/developers/smack?view=documents#/

So that it doesn’t get lost later.