如何使用 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());,其中mConnectionorg.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

android中的XMPP连接使用smack

如何使用 Smack Android 库将 XMPP IQ 节发送到服务器?

使用 xmpp + smack + openfire 在 android 中阻止用户

使用 Smack Android 将字符串转换为 XMPP 节

Android XMPP 聊天单刻度线以及如何从日志中读取 h 值