javaandroidsocketsxmppasmack

Send and Receive IQ XMPP ASMACK Android


Background:

I have been able to implement one to one chatting through XMPP in android using asmack library. I am able to send presence to the server as well. I am using OpenFire server for my Chat based application.

Problem: I am using connection.addPacketListener(new PacketListener() to receive message and IQ packets, for message packets I have classified it like this

PacketFilter Chatfilter = new MessageTypeFilter(Message.Type.chat);
connection.addPacketListener(new PacketListener() {
        public void processPacket(Packet packet) {
            Message message = (Message) packet;
            if (message.getBody() != null) {
                String fromName = StringUtils.parseBareAddress(message.getFrom());
                Log.i("XMPPClient", "Got text [" + message.getBody() + "] from [" + fromName + "]");
                messages.add(fromName + ":");
                m1=message.getBody();
                messages.add(message.getBody());
                // Add the incoming message to the list view
                /* mHandler.post(new Runnable() {
                public void run() {
                setListAdapter();
                recieve.setText(m1);
                }
                });*/
            }
        }
}, Chatfilter);

And it is working all fine, but problem arises when I use something similar to receive IQ packets

Here is the code which I am using to receive IQ PACKETS

PacketFilter Iqfilter = new IQTypeFilter(IQ.Type.RESULT);
connection.addPacketListener(new PacketListener() {
    public void processPacket(Packet packet) {
        IQ iq = (IQ) packet;
        String fromName = StringUtils.parseBareAddress(iq.getFrom());
        Log.i("XMPPClient", "Got text [" + iq.toString() + "] from [" + fromName + "]");
        m1=iq.getFrom();
        mHandler.post(new Runnable() {
            public void run() {
                setListAdapter();
                recieve.setText(m1);
            }
        });
    }
}, Iqfilter);

I am sending a simple disco#items query and it does not respond, even it does not enter into the function, I have tried to debug it as well, I have also tried to send simple PING command but it does not respond to it either. what am I missing here?

Secondly I am facing problems in sending IQ packets to the server as well or to some other client as well. I read somewhere that I should do it like this. but it does not work.

final IQ iq = new IQ() {
            public String getChildElementXML() { 
            return "<query xmlns='http://jabber.org/protocol/disco#info'/>"; // here is your query
            //this returns "<iq type='get' from='User@YourServer/Resource' id='info1'> <query xmlns='http://jabber.org/protocol/disco#info'/></iq>";
             }};
            // set the type
            iq.setType(IQ.Type.GET);

            // send the request
            connection.sendPacket(iq);

The confusing thing is when I read the documentation of XMPP and asmack for android it was written that to send an IQ you need to have receiver's address as well. but in this code we are not setting up any receiver.

There is much less information available on internet for XMPP asmack and Android.


Solution

  • I think the problem is that your providers aren't registered. Please take a look at this. On Android you have to register the providers manually before you form an XMPP connection. Copy the class below into your project

    import org.jivesoftware.smack.provider.PrivacyProvider;
    import org.jivesoftware.smack.provider.ProviderManager;
    import org.jivesoftware.smackx.GroupChatInvitation;
    import org.jivesoftware.smackx.PrivateDataManager;
    import org.jivesoftware.smackx.packet.ChatStateExtension;
    import org.jivesoftware.smackx.packet.LastActivity;
    import org.jivesoftware.smackx.packet.OfflineMessageInfo;
    import org.jivesoftware.smackx.packet.OfflineMessageRequest;
    import org.jivesoftware.smackx.packet.SharedGroupsInfo;
    import org.jivesoftware.smackx.provider.AdHocCommandDataProvider;
    import org.jivesoftware.smackx.provider.BytestreamsProvider;
    import org.jivesoftware.smackx.provider.DataFormProvider;
    import org.jivesoftware.smackx.provider.DelayInformationProvider;
    import org.jivesoftware.smackx.provider.DiscoverInfoProvider;
    import org.jivesoftware.smackx.provider.DiscoverItemsProvider;
    import org.jivesoftware.smackx.provider.MUCAdminProvider;
    import org.jivesoftware.smackx.provider.MUCOwnerProvider;
    import org.jivesoftware.smackx.provider.MUCUserProvider;
    import org.jivesoftware.smackx.provider.MessageEventProvider;
    import org.jivesoftware.smackx.provider.MultipleAddressesProvider;
    import org.jivesoftware.smackx.provider.RosterExchangeProvider;
    import org.jivesoftware.smackx.provider.StreamInitiationProvider;
    import org.jivesoftware.smackx.provider.VCardProvider;
    import org.jivesoftware.smackx.provider.XHTMLExtensionProvider;
    import org.jivesoftware.smackx.search.UserSearch;
    
    import android.util.Log;
    
    public class ServiceProviders {
        public static void Register_Providers(ProviderManager pm) {
    
            // Private Data Storage
            pm.addIQProvider("query", "jabber:iq:private",
                    new PrivateDataManager.PrivateDataIQProvider());
    
            // Time
            try {
                pm.addIQProvider("query", "jabber:iq:time",
                        Class.forName("org.jivesoftware.smackx.packet.Time"));
            } catch (ClassNotFoundException e) {
                Log.w("TestClient",
                        "Can't load class for org.jivesoftware.smackx.packet.Time");
            }
    
            // Roster Exchange
            pm.addExtensionProvider("x", "jabber:x:roster",
                    new RosterExchangeProvider());
    
            // Message Events
            pm.addExtensionProvider("x", "jabber:x:event",
                    new MessageEventProvider());
    
            // Chat State
            pm.addExtensionProvider("active",
                    "http://jabber.org/protocol/chatstates",
                    new ChatStateExtension.Provider());
    
            pm.addExtensionProvider("composing",
                    "http://jabber.org/protocol/chatstates",
                    new ChatStateExtension.Provider());
    
            pm.addExtensionProvider("paused",
                    "http://jabber.org/protocol/chatstates",
                    new ChatStateExtension.Provider());
    
            pm.addExtensionProvider("inactive",
                    "http://jabber.org/protocol/chatstates",
                    new ChatStateExtension.Provider());
    
            pm.addExtensionProvider("gone",
                    "http://jabber.org/protocol/chatstates",
                    new ChatStateExtension.Provider());
    
            // XHTML
            pm.addExtensionProvider("html", "http://jabber.org/protocol/xhtml-im",
                    new XHTMLExtensionProvider());
    
            // Group Chat Invitations
            pm.addExtensionProvider("x", "jabber:x:conference",
                    new GroupChatInvitation.Provider());
    
            // Service Discovery # Items
            pm.addIQProvider("query", "http://jabber.org/protocol/disco#items",
                    new DiscoverItemsProvider());
    
            // Service Discovery # Info
            pm.addIQProvider("query", "http://jabber.org/protocol/disco#info",
                    new DiscoverInfoProvider());
    
            // Data Forms
            pm.addExtensionProvider("x", "jabber:x:data", new DataFormProvider());
    
            // MUC User
            pm.addExtensionProvider("x", "http://jabber.org/protocol/muc#user",
                    new MUCUserProvider());
    
            // MUC Admin
            pm.addIQProvider("query", "http://jabber.org/protocol/muc#admin",
                    new MUCAdminProvider());
    
            // MUC Owner
            pm.addIQProvider("query", "http://jabber.org/protocol/muc#owner",
                    new MUCOwnerProvider());
    
            // Delayed Delivery
            pm.addExtensionProvider("x", "jabber:x:delay",
                    new DelayInformationProvider());
    
            // Version
            try {
                pm.addIQProvider("query", "jabber:iq:version",
                        Class.forName("org.jivesoftware.smackx.packet.Version"));
            } catch (ClassNotFoundException e) {
                // Not sure what's happening here.
            }
    
            // VCard
            pm.addIQProvider("vCard", "vcard-temp", new VCardProvider());
    
            // Offline Message Requests
            pm.addIQProvider("offline", "http://jabber.org/protocol/offline",
                    new OfflineMessageRequest.Provider());
    
            // Offline Message Indicator
            pm.addExtensionProvider("offline",
                    "http://jabber.org/protocol/offline",
                    new OfflineMessageInfo.Provider());
    
            // Last Activity
            pm.addIQProvider("query", "jabber:iq:last", new LastActivity.Provider());
    
            // User Search
            pm.addIQProvider("query", "jabber:iq:search", new UserSearch.Provider());
    
            // SharedGroupsInfo
            pm.addIQProvider("sharedgroup",
                    "http://www.jivesoftware.org/protocol/sharedgroup",
                    new SharedGroupsInfo.Provider());
    
            // JEP-33: Extended Stanza Addressing
            pm.addExtensionProvider("addresses",
                    "http://jabber.org/protocol/address",
                    new MultipleAddressesProvider());
    
            // FileTransfer
            pm.addIQProvider("si", "http://jabber.org/protocol/si",
                    new StreamInitiationProvider());
    
            pm.addIQProvider("query", "http://jabber.org/protocol/bytestreams",
                    new BytestreamsProvider());
    
            // Privacy
            pm.addIQProvider("query", "jabber:iq:privacy", new PrivacyProvider());
    
            pm.addIQProvider("command", "http://jabber.org/protocol/commands",
                    new AdHocCommandDataProvider());
            pm.addExtensionProvider("malformed-action",
                    "http://jabber.org/protocol/commands",
                    new AdHocCommandDataProvider.MalformedActionError());
            pm.addExtensionProvider("bad-locale",
                    "http://jabber.org/protocol/commands",
                    new AdHocCommandDataProvider.BadLocaleError());
            pm.addExtensionProvider("bad-payload",
                    "http://jabber.org/protocol/commands",
                    new AdHocCommandDataProvider.BadPayloadError());
            pm.addExtensionProvider("bad-sessionid",
                    "http://jabber.org/protocol/commands",
                    new AdHocCommandDataProvider.BadSessionIDError());
            pm.addExtensionProvider("session-expired",
                    "http://jabber.org/protocol/commands",
                    new AdHocCommandDataProvider.SessionExpiredError());
    
            pm.addIQProvider("query", "http://jabber.org/protocol/disco#info",
                    new DiscoverInfoProvider());
            pm.addExtensionProvider("x", "jabber:x:data", new DataFormProvider());
            // pm.addExtensionProvider("status ","", new XMLPlayerList());
    
        }
    }
    

    Call this method like this

    ServiceProviders.Register_Providers(ProviderManager.getInstance());
    

    So try calling this method at the start of your app or before forming a connection.

    Hope this helps