如何从XMPP XML消息中获取自定义属性值?

时间:2012-03-23 10:57:03

标签: java android xmpp smack

好的,简单的问题,但对我来说非常重要。

所以,其他android客户端正在发送这个xml msg:

<message
  id='6ymdM-19'
  to='xox@xox.xox/smack'
  type='chat'>
  <subject>normal</subject>
  <received xmlns='urn:xmpp:receipts' id='HVgQw-5'/>
</message>

我的听众大致是这样的:

private class MsgListener implements ChatStateListener {
/**
 * Constructor.
 */
public MsgListener() {
}

@Override
public void processMessage(Chat chat, org.jivesoftware.smack.packet.Message message) {
    String xmlMessage = message.toXML();
    Log.v(TAG, "XML Chat: "+xmlMessage);
    // getExtension namespace try urn:xmpp:receipts
    if(xmlMessage.contains("<request xmlns=")) {
        Log.d(TAG, "new chat message arrive! reply with RECEIVED!");
        replyReceived(message);
    } else if(xmlMessage.contains("<received xmlns=")) {
        Log.d(TAG, "RECEIVED notification arrived!");
        PacketExtension statusExtension = 
                message.getExtension("urn:xmpp:receipts");
        Log.d(TAG, "Extension name: "+statusExtension.getElementName());
        Log.d(TAG, "Extension XML: "+statusExtension.toXML());
        Log.d(TAG, "Extension string: "+statusExtension.toString());
    }

     ....
     ....
     ....
} 

在这种情况下,我想在“received”元素标记内获取属性“id”的值。 但我在我的日志上得到的是这样的:

RECEIVED notification arrived!
D/ChatAdapter(320): Extension name: received
D/ChatAdapter(320): Extension XML: <received xmlns="urn:xmpp:receipts"></received>
D/ChatAdapter(320): Extension string:              
org.jivesoftware.smack.packet.DefaultPacketExtension@44f10430

那我怎么能得到'HVgQw-5'?

更新

实际上有些奇怪...... 我从我的SMACK调试中收到了xml accordinh:

 <
 D/SMACK(320): 05:40:28 PM RCV  (1156991856): message id="6ymdM-19"  
 to="syeikh@emass.sangkuriang.co.id/Smack" from="emu22@emass.sangkuriang.co.id/Smack"  
 type="chat"><subject>
 D/SMACK(320): 05:40:28 PM RCV  (1156991856): normal</subject><thread>cr0900</thread>
 **<received xmlns="urn:xmpp:receipts" id="HVgQw-5"/>**<active      
 xmlns="http://jabber.org/protoc
 D/SMACK(320): 05:40:28 PM RCV  (1156991856): ol/chatstates"/></message>

但是当我执行message.toXML时,它就像这样打印出来:

XML Chat: <message id="6ymdM-19" to="syeikh@emass.sangkuriang.co.id/Smack" from="emu22@emass.sangkuriang.co.id/Smack" type="chat"><subject>normal</subject><thread>cr0900</thread>**<received xmlns="urn:xmpp:receipts">**</received><active xmlns="http://jabber.org/protocol/chatstates" /></message>

为什么会这样?为什么我会错过“id”?

3 个答案:

答案 0 :(得分:12)

关于ID,首先获取扩展句柄然后查找ID,所以

DeliveryReceipt deliveryReceiptObj =(DeliveryReceipt) message.getExtension(DeliveryReceipt.NAMESPACE);
// ID below is what you want
deliveryReceiptObj.getId();

相关讨论: asmack - receiving custom XML messages

  1. 定义您的EmbeddedPacketExtension(因此您可以处理此问题,而不是SMACK提供的DefaultPacketExtension

  2. 扩展EmbeddedExtensionProvider

  3. 的提供商 您刚刚使用命名空间

    创建的
  4. registerProvider

    代码如下:

    /**
    * User: suvrat 
    * Represents a <b>message delivery receipt</b> entry as specified by
    * <a href="http://xmpp.org/extensions/xep-0184.html">Message Delivery Receipts</a>.
    *
    */
    
    import org.jivesoftware.smack.packet.PacketExtension;
    
    public class DeliveryReceipt implements PacketExtension
    {
    
        public static final String NAMESPACE = "urn:xmpp:receipts";
    
        private String id; /// original ID of the delivered message
    
        public DeliveryReceipt(String id)
        {
            this.id = id;
        }
    
        public String getId()
        {
            return id;
        }
    
        public String getElementName()
        {
            return "received";
        }
    
        public String getNamespace()
        {
            return NAMESPACE;
        }
    
        public String toXML()
        {
            return "<received xmlns='" + NAMESPACE + "' id='" + id + "'/>";
        }
    }
    
     /**
     * User: suvrat
     * The DeliveryReceiptProvider parses DeliveryReceipt packets.
     */
    
     */
    import org.jivesoftware.smack.packet.PacketExtension;
    import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
    import org.xmlpull.v1.XmlPullParser;
    
    import java.util.List;
    import java.util.Map;
    
    public class DeliveryReceiptProvider extends EmbeddedExtensionProvider
    {
    
        @Override
        protected PacketExtension createReturnExtension(String currentElement, String currentNamespace,
        Map<String, String> attributeMap, List<? extends PacketExtension> content)
        {
            return new DeliveryReceipt(attributeMap.get("id"));
        }
    
    }
    
       //3.) finally where ever you would like to parse packet
     ProviderManager.getInstance().addExtensionProvider("received", DeliveryReceipt.NAMESPACE, new DeliveryReceiptProvider());
    

答案 1 :(得分:0)

不修改源代码就无法实现它。 XMPP中正确的方法是为标准数据包创建扩展,而不是对其进行修改。 您可以参考Cannot Read Custom Attributes From Message TAG when using asmack XMPP library for android?,其中提供了详细信息。

答案 2 :(得分:0)

还有另一种获取属性值的方法,该方法通过实现ExtensionElement来定义方法UserInfo4XMPP:

import org.jivesoftware.smack.packet.ExtensionElement;
public class UserInfo4XMPP implements ExtensionElement{
    public static final String NAMESPACE = "urn:xmpp:receipts";
    private String elementName = "received ";
    private String id = "";    
    @Override
    public String getElementName() {
        return elementName;
    }
        @Override
    public CharSequence toXML() {  
        return "<received xmlns='" + NAMESPACE + "' id='" + id + "'/>";
    }
    @Override
    public String getNamespace() {
        return NAMESPACE;
    }
    public String getId()
    {
        return id;
    }
}

功能主体类似于DeliveryReceiptProvider。