5

我在一个android项目中使用asmack最新版本(asmack-android-8-source-0.8.3),我有以下代码:

connection.addPacketListener(new PacketListener()
{
    @Override
    public void processPacket(Packet p)
    {
        if(p.getPacketID().equals("v3"))
        {
            Log.e("TAG", p.toXML());
        }
    }
}, new IQTypeFilter(IQ.Type.RESULT));


Packet iq = new Packet() 
{
    @Override
    public String toXML() 
    {
        String str = "<iq type='get' id='v3'><getservertime xmlns='urn:xmpp:mrpresence'/></iq>";
        Log.e("TAG", str);
        return str;
    }
};

//sends <iq type='get' id='v3'><getservertime xmlns='urn:xmpp:mrpresence'/></iq>
connection.sendPacket(iq);

在调试器中,响应没问题,这是预期的:

<iq type="result" id="v3" to="minimaal@mrserver/Smack">
    <servertime xmlns="urn:xmpp:mrpresence" utc="2013-06-28T11:45:32.380Z" local="2013-06-28T07:45:32.380Z"/>
</iq>

但是包列表器中的 p.toXML() 缺少标签“servertime”:

<iq id="v3" to="minimaal@mrserver/Smack" type="result"></iq>

关于我做错了什么有什么建议吗?

4

2 回答 2

3

我通过扩展 IQ 和 IQProvider 类解决了这个问题:

ServerTime_IQProvider.java

public class ServerTime_IQProvider implements IQProvider
{
    public static final String NAMESPACE = "urn:xmpp:mrpresence";
    public static final String ELEMENT_NAME = "servertime";
    public static final String UTC = "utc";
    public static final String LOCAL = "local";
    private Map<String, String> list = new HashMap<String, String>();

    @Override
    public IQ parseIQ(XmlPullParser parser) throws Exception
    {
        boolean stop = false;
        String name = parser.getName();

        while(false == stop)
        {
            switch (parser.getEventType())
            {
                case XmlPullParser.START_TAG:
                {
                    if(ELEMENT_NAME.equals(name))
                    {
                        list.put(UTC, parser.getAttributeValue("", UTC));
                        list.put(LOCAL, parser.getAttributeValue("", LOCAL));
                    }

                    break;
                }
                case XmlPullParser.END_TAG:
                {
                    stop = ELEMENT_NAME.equals(name);
                    break;
                }
            }
        }

        name = null;
        return new ServerTime_IQ(list);
    }
}

ServerTime_IQ.java

public class ServerTime_IQ extends IQ
{
    public static final String ID = "servertime";
    private Map<String, String> list;

    public ServerTime_IQ(Map<String, String> l)
    {
        list = l;
    }

    @Override
    public String getChildElementXML()
    {
        return null;
    }

    public String getServerTime_UTC()
    {
        return list.get(ServerTime_IQProvider.UTC);
    }

    public String getServerTime_Local()
    {
        return list.get(ServerTime_IQProvider.LOCAL);
    }
}

然后我将 ServerTime 提供程序添加到 IQProvider 的列表中:

ProviderManager.getInstance().addIQProvider(ServerTime_IQProvider.ELEMENT_NAME, ServerTime_IQProvider.NAMESPACE, new ServerTime_IQProvider());

这将确保来自服务器的 xml 响应将使用我的自定义解析器 (ServerTime_IQProvider) 进行解析,该解析器知道自定义标签,而不是 asmack 的默认解析器。

于 2013-07-05T07:53:58.600 回答
3

<servertime/>是一个自定义子元素,Smack 不知道它。解析节时它被简单地忽略。您需要通过创建一个需要ProviderManager.

您可以在 Smack 关于Provider Architecture的文档中阅读更多相关信息。

于 2013-06-28T17:38:33.523 回答