Brief Tutorial on IQ Providers

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 SET

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.equals("myData")){

                                                                          myIQ.setmyData(Float.parseFloat(parser.nextText()));

                                                           }

                                           }

                           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 then 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() {

            }

            @Override

            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)

                           reply.setPacketID(packet.getPacketID());

                           reply.setFrom(packet.getTo());

                           reply.setTo(packet.getFrom());

                           connection.sendPacket(reply);

                  }

}

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.

What is the version of smack u used ?

@Mithun can you help me please i following same as above Chat App for Android using a XMPP Server and Firebase Cloud Messaging for Push Notifications - Stack Overflow

This is out of date!!!

CustomIQ class Is not working with SMACK 4.2.0.

As getChldElementXML() expects an IQChildElementXmlStringBuilder object on return not a String.