如何使用 SMACK 在 Android XMPP 客户端中解析自定义花名册查询响应
Posted
技术标签:
【中文标题】如何使用 SMACK 在 Android XMPP 客户端中解析自定义花名册查询响应【英文标题】:How to parse custom roster query response in Android XMPP client with SMACK 【发布时间】:2015-02-26 16:24:22 【问题描述】:就目前而言,我对 XMPP 和 SMACK 总体上了解甚少,所以如果我的问题不准确,请见谅。
登录后,我收到的数据包如下:
<iq id="8CiUQ-1" type="result">
<query xmlns="jabber:iq:roster">
<item jid="625126126@saomeapp-test.cloudapp.net" name="Aziez" subscription="both" msgblock="none"/>
<item jid="547657221@saomeapp-test.cloudapp.net" name="Kmil" subscription="both" msgblock="none"/>
<item jid="553269257@saomeapp-test.cloudapp.net" name="grzegorz" subscription="both" msgblock="none"/>
<item jid="683494364@saomeapp-test.cloudapp.net" name="Wiktor2" subscription="both" msgblock="none"/>
<item jid="602914857@saomeapp-test.cloudapp.net" name="Art" subscription="both" msgblock="none"/>
<item jid="634926524@saomeapp-test.cloudapp.net" name="ml" subscription="both" msgblock="none"/>
</query>
</iq>
我知道这一点,因为我可以看到这个数据包在 SMACK 标记下打印到我的 logcat。
我需要访问msgblock
参数。 org.jivesoftware.smack.RosterEntry
类将没有 msgblock
参数的 getter,因为它是此服务器实现的自定义(我想)。那么如何访问msgblock
参数呢?
这是我尝试过的:
我打电话给:mConnection.addPacketListener(new RosterPacketListener(), new RosterPacketFilter());
,其中mConnection
是org.jivesoftware.smack.XMPPConnection;
的一个实例。
过滤器看起来像这样:
private class RosterPacketFilter implements PacketFilter
@Override
public boolean accept(Packet packet)
return packet instanceof RosterPacket;
听众:
private class RosterPacketListener implements PacketListener
@Override
public void processPacket(Packet packet)
Log.d("tag", packet.toXML());
我完全不明白的部分是Log.d("tag", packet.toXML());
的输出不包含msgblock
参数。如何访问我的名册中的msgblock
参数?
【问题讨论】:
msgblock
看起来像一个非标准属性。你不应该依赖这些。如果你在发明它的人那里,那么你不应该发明那些。
@Flow:确实如此,as per documentation roster item 不包含此参数。不幸的是,我不是我添加这个的,所以我正在寻找解决这个问题的方法。
请注意,RFC3121 已被弃用,您应该参考 RFC 6121。获取非标准属性值的唯一方法是修补 Smack 的内部结构
@Flow 有没有办法在传入的数据包被反序列化为 SMACK 的 Packet 对象之前拦截其原始形式的传入数据包?
最终使用调试器。但我高度怀疑这是要走的路。答案是:不,没有。而且你不应该使用这些属性。
【参考方案1】:
无需为连接对象添加自定义数据包监听器。
从服务器获取所有名册
Roster roster = mConnection.getRoster();
// collection of RosterEntry from roster object
Collection<RosterEntry> entries= roster.getEntries();
for(RosterEntry entry : entries)
Log.i("RosterName", "Name : "+ entry.getName());
Log.i("RosterName", "Name : "+ entry.getUser());
【讨论】:
以上是关于如何使用 SMACK 在 Android XMPP 客户端中解析自定义花名册查询响应的主要内容,如果未能解决你的问题,请参考以下文章
如何将自定义字段放入 XMPP vCard Android/SMACK
如何使用 Smack Android 库将 XMPP IQ 节发送到服务器?
使用 xmpp + smack + openfire 在 android 中阻止用户