Send and Receive IQ XMPP ASMACK Android
Asked Answered
A

3

9

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.

Aldaaldan answered 12/3, 2014 at 7:1 Comment(0)
L
4

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

Litmus answered 12/3, 2014 at 9:37 Comment(6)
Great, now I am getting the response at one side and this is amazing thank you so much, but now how can i reply back to the server. for example i am using xmpp analyzer and i send disco#items query to my client which was received by my client, but client did not respond back to server. do i need to add response handler or something like that?Aldaaldan
Secondly, how can I send raw xml query to server from client.? am i missing something there as well in the code?Aldaaldan
@HassaanRabbani Nic to know that the above solution worked. I haven't played too much with asmack xmpp and i haven't had experience with using disco#items query.So I suggest you make another question for this so that people who have more experience than me can guide you. If the above answer solved your problem then please accept it :)Litmus
the above solution worked for one problem, that is receiving the IQ, what about sending the IQ? how can i send an IQ to the client from another client or from client to server?Aldaaldan
Take a look at this groups.google.com/forum/#!topic/prosody-users/8IW2t2i45Uk and community.igniterealtime.org/thread/40941Litmus
Is this features available on Smack library ?Nigeria
M
0

For sent out, you actually just need to construct the xml string and return in getChildElementXML(), no other setup needed.

As mentioned in this blog post: https://billynyh.github.io/blog/2014/09/28/android-xmpp-dev/

For receiving IQ response, first you need to create IQProvider and add to ProviderManager, matching the xmlns in the query object. The IQProvider is used to convert the response packet to your customized IQ object. Then you need to extends PacketListener, and when you create the connection object, add the listener to it, with a PacketTypeFilter to match your IQ class. With both provider and listener setup correctly, you should be able to receive the response of the IQ.

Mikimikihisa answered 27/6, 2018 at 11:30 Comment(0)
S
0

When sending a self-define message, for example,

<iq id='123' type='get' from='client@xmpp/B' to='client2@xmpp/s2'><req var='read'><attr var='temprature'/></req></iq>

You need to define your own IQ and send this IQ:

public class MyIQ extends IQ {
        @Override
        public String getChildElementXML() {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("&lt;req var='read'&gt;&lt; attr var='temprature'/&gt;&lt;/req&gt;");
            return stringBuilder.toString();
        }
    }

    MyIQ packet = new MyIQ();
    packet.setType(IQ.Type.GET);
    packet.setFrom("client@xmpp/B");
    packet.setTo("client2@xmpp/s2");
    xmppConnection.sendPacket(packet);
Sherrellsherrer answered 29/6, 2018 at 13:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.