背景
我已经能够使用XMPP
库在android中通过asmack
进行一对一聊天。我也可以向服务器发送状态。我在基于聊天的应用程序中使用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 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);
我正在发送一个简单的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在互联网上提供的信息要少得多。
答案 0 :(得分:4)
我认为问题在于您的提供商尚未注册。请看this。在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());
因此,请尝试在应用开始时或在建立连接之前调用此方法。
希望这有帮助
答案 1 :(得分:0)
对于发送出去,您实际上只需要构造xml字符串并返回getChildElementXML(),而无需其他设置。
要接收IQ响应,首先需要创建IQProvider并将其添加到ProviderManager中,以匹配查询对象中的xmlns。 IQProvider用于将响应数据包转换为自定义的IQ对象。然后,您需要扩展PacketListener,并在创建连接对象时,使用PacketTypeFilter将侦听器添加到该侦听器以匹配您的IQ类。通过正确设置提供者和侦听器,您应该能够收到IQ的响应。
这里是参考:https://billynyh.github.io/blog/2014/09/28/android-xmpp-dev/
答案 2 :(得分: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("<req var='read'>< attr var='temprature'/></req>");
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);