Stanza for Smack 4.1.4 中的自定义扩展元素

Posted

技术标签:

【中文标题】Stanza for Smack 4.1.4 中的自定义扩展元素【英文标题】:Custom extension element in Stanza for Smack 4.1.4 【发布时间】:2015-10-05 03:29:57 【问题描述】:

我正在将我的 android 应用程序从 asmack-android 库移动到 Smack 4.1.4。我在 Smack 的 asmack 版本中有一些 PacketExtensions,它使用 PacketExtension 和 PacketExtensionProvider 类来处理。由于 PacketExtension 在 Smack 4.1.4 中已弃用,我对 ExtensionElement、DataPacketExtension、ExtensionElementProvider 和 DefaultExtensionElement 类和接口感到困惑。你们中的任何人都可以给我一个创建扩展的示例,该扩展可以添加节并解析回来...https://www.igniterealtime.org/builds/smack/docs/latest/javadoc/org/jivesoftware /smack/packet/DefaultExtensionElement.htmlhttps://www.igniterealtime.org/builds/smack/docs /latest/javadoc/org/jivesoftware /smack/provider/ExtensionElementProvider.html

【问题讨论】:

【参考方案1】:
Message message = new Message();
message.setStanzaId("923442621149");
message.setType(Type.chat);
message.setBody("shanraisshan");
Log.e("message --->", message.toXML().toString());

这将产生以下节

<message id='923442621149' type='chat'><body>shanraisshan</body></message>

1。 自定义扩展节类型 1

为了生成下面的自定义扩展节

<message id='923442621149' type='chat'><body>shanraisshan</body>
<reply xmlns='shayan:reply' rText='this is custom attribute'/>
</message>

其中 reply 是自定义扩展,其中包含

    元素(回复) 命名空间 (shayan:reply)

默认 xmpp 命名空间列表位于 Official XMPP website

执行以下步骤

1.在您的项目中添加 ReplyExtension.java

ReplyExtension.java

package com.xmpp.extensions;

import org.jivesoftware.smack.packet.DefaultExtensionElement;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.provider.EmbeddedExtensionProvider;
import org.jivesoftware.smack.util.XmlStringBuilder;
import java.util.List;
import java.util.Map;

/**
 * Shayan Rais (http://shanraisshan.com)
 * created on 9/7/2016
 */
public class ReplyExtension implements ExtensionElement  

    public static final String NAMESPACE = "shayan:reply";
    public static final String ELEMENT = "reply";

    String rText = null;

    static final String ATTRIBUTE_REPLY_TEXT = "rText";

    @Override
    public String getElementName() 
        return ELEMENT;
    

    @Override
    public String getNamespace() 
        return NAMESPACE;
    

    @Override
    public XmlStringBuilder toXML() 
        XmlStringBuilder xml = new XmlStringBuilder(this);
        xml.attribute(ATTRIBUTE_REPLY_TEXT, getReplyText());
        xml.closeEmptyElement();
        return xml;
    

//__________________________________________________________________________________________________
    public void setReplyText(String _rText) 
        rText = _rText;
    

    public String getReplyText() 
        return rText;
    

//__________________________________________________________________________________________________
    public static class Provider extends   EmbeddedExtensionProvider<ReplyExtension> 
        @Override
        protected ReplyExtension createReturnExtension(String    currentElement, String currentNamespace, Map<String, String> attributeMap,    List<? extends ExtensionElement> content) 
            ReplyExtension repExt = new ReplyExtension();
            repExt.setReplyText(attributeMap.get(ATTRIBUTE_REPLY_TEXT));
            return repExt;
        
    

2.在您的 Provider Manager 中注册 ReplyExtension

ProviderManager.addExtensionProvider(ReplyExtension.ELEMENT, ReplyExtension.NAMESPACE, new ReplyExtension.Provider());

用于发送消息

您可以使用以下代码生成自定义扩展节 TYPE-1

Message message = new Message();
message.setStanzaId("923442621149");
message.setType(Type.chat);
message.setBody("shanraisshan");
//adding custom reply extension
ReplyExtension repExt = new ReplyExtension();
repExt.setReplyText("this is custom attribute");
message.addExtension(repExt);
Log.e("message --->", message.toXML().toString());

在接收消息期间

现在在接收自定义扩展节时,您需要强制转换扩展以获取属性值。

//check for message with reply extension
ExtensionElement packetExtension =  message.getExtension(ReplyExtension.NAMESPACE);
ReplyExtension repExt = (ReplyExtension)packetExtension;
if(repExt!=null) 
    Log.e("--->", " ---  LOG REPLY EXTENSION ---");
    Log.e("--->", repExt.toXML() + "");
    Log.e("--->", repExt.getReplyText() + ""); //this is custom attribute


______________________________________________

2。 自定义扩展节类型 2

为了生成下面的自定义扩展节

<message id='923442621149' type='chat'><body>shanraisshan</body>
<reply xmlns='shayan:reply'><rText>this is custom attribute</rText></reply>
</message>

用于发送消息

您可以使用以下代码生成自定义扩展节 TYPE-2

Message message = new Message();
message.setStanzaId("923442621149");
message.setType(Type.chat);
message.setBody("shanraisshan");
//adding custom reply extension
DefaultExtensionElement repExt = new DefaultExtensionElement("reply", "shayan:reply");
repExt.setValue("rText", "this is custom attribute");
message.addExtension(repExt);
Log.e("message --->", message.toXML().toString());

在接收消息期间

DefaultExtensionElement repExt = (DefaultExtensionElement) message.getExtension("shayan:reply");
if(repExt!=null) 
    Log.e("--->", " ---  LOG REPLY EXTENSION ---");
    Log.e(getClass().getSimpleName(), repExt.getValue("rText"));

【讨论】:

【参考方案2】:

终于想通了....这是解决方案...

import org.jivesoftware.smack.packet.DefaultExtensionElement;

public class IM_FileSharing_Extension extends DefaultExtensionElement implements
    IM_Commons_Extension_FileSharing 

private String fileUrl;
private String fileType;
private String base64preview;
private String fileId;
private String fileSize;

public IM_FileSharing_Extension(String fileUrl, String fileType,
        String base64preview, String fileId, String fileSize) 
    super(FILE_TAG, XMLNS);
    this.fileUrl = fileUrl;
    this.fileType = fileType;
    this.base64preview = base64preview;
    this.fileId = fileId;
    this.fileSize = fileSize;


@Override
public String toXML() 

    StringBuilder sb = new StringBuilder("<" + FILE_TAG + " xmlns=\""
            + XMLNS + "\" ");
    sb.append(FILE_URL + "=\"" + fileUrl + "\" ");
    sb.append(FILE_ID + "=\"" + fileId + "\" ");
    sb.append(FILE_TYPE + "=\"" + fileType + "\" ");
    sb.append(FILE_SIZE + "=\"" + fileSize + "\">");
    sb.append("<" + FILE_PREVIEW_TAG + ">" + base64preview + "</"
            + FILE_PREVIEW_TAG + ">");
    sb.append("</" + FILE_TAG + ">");

    return sb.toString();


public String getFileUrl() 
    return fileUrl;


public void setFileUrl(String fileUrl) 
    this.fileUrl = fileUrl;


public String getBase64preview() 
    return base64preview;


public void setBase64preview(String base64preview) 
    this.base64preview = base64preview;


public String getFileId() 
    return fileId;


public void setFileId(String fileId) 
    this.fileId = fileId;


public String getFileType() 
    return fileType;


public void setFileType(String fileType) 
    this.fileType = fileType;


public String getFileSize() 
    return fileSize;


public void setFileSize(String fileSize) 
    this.fileSize = fileSize;



上述扩展的提供者如下...

import java.io.IOException;

import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.provider.ExtensionElementProvider;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.util.Log;

public class IM_FileSharingExtension_Provider extends
    ExtensionElementProvider<IM_FileSharing_Extension> implements
    IM_Commons_Extension_FileSharing 
static final String TAG = "file_extension";

@Override
public IM_FileSharing_Extension parse(XmlPullParser parser, int initialDepth)
        throws XmlPullParserException, IOException, SmackException 

    IM_FileSharing_Extension fileExtension = null;

    boolean stop = false;

    String n = null;

    int evtType;

    String fileUrl = null;
    String fileType = null;
    String fileId = null;
    String fileSize = null;
    while (!stop) 

        evtType = parser.getEventType();
        n = parser.getName();
        Log.d(TAG, "n:" + n + " evt:" + evtType);
        switch (evtType) 

        case XmlPullParser.START_TAG:

            if (FILE_TAG.equals(n)) 

                fileUrl = parser.getAttributeValue("", FILE_URL);

                fileType = parser.getAttributeValue("", FILE_TYPE);

                fileId = parser.getAttributeValue("", FILE_ID);

                fileSize = parser.getAttributeValue("", FILE_SIZE);

                evtType = parser.next();

            

            if (FILE_PREVIEW_TAG.equals(parser.getName())) 
                String basePreview = parser.nextText();
                fileExtension = new IM_FileSharing_Extension(fileUrl,
                        fileType, basePreview, fileId, fileSize);
            

            evtType = parser.next();

            break;

        case XmlPullParser.END_TAG:

            if (parser.getName().equals(FILE_TAG)) 
                return fileExtension;
            
            evtType = parser.next();

        

    
    return null;



并且应该在Provider manager中添加如下......

ProviderManager.addExtensionProvider(
            IM_Commons_Extension_FileSharing.FILE_TAG,
            IM_Commons_Extension_FileSharing.XMLNS,
            new IM_FileSharingExtension_Provider());

【讨论】:

以上是关于Stanza for Smack 4.1.4 中的自定义扩展元素的主要内容,如果未能解决你的问题,请参考以下文章

使用 Smack 接收自定义 XMPP 节

我如何在 smack openfire android 中监听传入的订阅请求

如何使用 smack-android:4.1.4 在多用户聊天室中解禁用户

使用stanza完成自然语言分析处理任务

使用 Smack Api for Android 发送和接收消息

使用 Ejabberd 和 Smack for Android 创建群聊功能的正确方法是啥?