发送和接收 IQ XMPP ASMACK Android

9

背景:

我已经能够在Android中使用asmack库通过XMPP实现一对一聊天。我也能够向服务器发送出席信息。我正在为我的聊天应用程序使用OpenFire服务器。

问题:

我正在使用connection.addPacketListener(new PacketListener()来接收消息和IQ数据包,对于消息数据包,我已将其分类如下:

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);

一切都运行正常,但是问题出现在我使用类似于接收 IQ 数据包的东西时。

以下是我用来接收 IQ 数据包的代码:

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);

我正在发送一个简单的disco#items查询,但它没有响应,甚至没有进入函数,我已尝试进行调试,也尝试发送简单的PING命令,但它也没有响应。我错过了什么吗?
其次,我在向服务器或其他客户端发送IQ数据包方面也遇到问题。我在某个地方读到我应该这样做,但它不起作用。
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);

读取XMPP和asmack for android的文档时,让我感到困惑的是,文档说要发送IQ消息就需要有接收者地址,但是在这段代码中我们并没有设置任何接收者。

关于XMPP asmack和Android的信息在互联网上相对较少。

3个回答

4
我认为问题在于您的提供商没有注册。请参考这个链接。在Android上,您必须手动注册提供程序,然后才能建立XMPP连接。将下面的类复制到您的项目中即可。
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());

    }
}

使用以下方式调用此方法

ServiceProviders.Register_Providers(ProviderManager.getInstance());

因此,请在应用程序启动或建立连接之前尝试调用此方法。

希望这可以帮到你。


太好了,现在我已经在一侧收到响应了,这太棒了,非常感谢。但是现在我该如何回复服务器呢?例如,我正在使用XMPP分析器,并向我的客户端发送disco#items查询,客户端已经接收到了该查询,但是客户端没有回复服务器。我需要添加响应处理程序或类似的东西吗? - Hassaan Rabbani
其次,我如何从客户端向服务器发送原始的 XML 查询?在代码中是否还有什么遗漏的地方? - Hassaan Rabbani
@HassaanRabbani 很高兴知道上面的解决方案起作用了。我没有太多使用 asmack xmpp 的经验,也没有使用 disco#items 查询的经验。因此,我建议您提出另一个问题,这样比我更有经验的人可以指导您。如果上面的答案解决了您的问题,请接受它 :) - Sheraz Ahmad Khilji
上面的解决方案适用于接收 IQ 的问题,那么发送 IQ 怎么办?我如何从另一个客户端或从客户端到服务器向客户端发送 IQ? - Hassaan Rabbani
请查看以下网址:https://groups.google.com/forum/#!topic/prosody-users/8IW2t2i45Uk 和 http://community.igniterealtime.org/thread/40941 - Sheraz Ahmad Khilji
Smack库是否支持这些功能? - Kamalakannan J

0

当发送自定义消息时,例如:

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

你需要定义自己的IQ并发送这个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);

0

对于发送,你只需要构造xml字符串并在getChildElementXML()中返回即可,不需要其他设置。

正如这篇博客文章所提到的:https://billynyh.github.io/blog/2014/09/28/android-xmpp-dev/

对于接收IQ响应,首先需要创建IQProvider并添加到ProviderManager中,与查询对象中的xmlns匹配。 IQProvider用于将响应数据包转换为您自定义的IQ对象。 然后需要扩展PacketListener,并在创建连接对象时将侦听器添加到其中,使用PacketTypeFilter来匹配您的IQ类。 如果提供程序和侦听器都正确设置,则应该能够接收IQ的响应。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接