【问题标题】:Android aSmack - How to make custom message extension for file sending?Android aSmack - 如何为文件发送自定义消息扩展名?
【发布时间】:2015-06-13 06:08:33
【问题描述】:

我正在尝试为我的聊天应用程序实现离线文件扩展名。我正在使用 PacketExtension 和 EmbeddedExtensionProvider 添加和解析自定义扩展。我可以看到在发送消息时添加了值和标签,但在接收端这些不存在。我做错了什么?

发送消息:

<message id="224K2-7" to="testfirzan@sushant" type="chat">
    <body>hi</body>
    <custom xmlns="jabber2:x2:oob2">
      <url>URL</url>
      <desc>Description</desc>
    </custom>
</message>

接收消息:

System.out(734): EmbeddedExtensionProvider

<message id="224K2-7" to="testfirzan@sushant" from="testsushant@sushant/Smack" type="chat">
    <body>hi</body>
    <custom xmlns="jabber2:x2:oob2"></custom>
</message>

File Extension description:(734): <custom xmlns="jabber2:x2:oob2"></custom>

数据包扩展和提供者管理器代码:

public class FileExtension implements PacketExtension {

public static final String ELEMENT = "custom";
public static final String NAMESPACE = "jabber2:x2:oob2";

String description;
String url;

@Override
public String getElementName() {
    return "custom";
}

@Override
public String getNamespace() {
    return "jabber2:x2:oob2";
}

@Override
public String toXML() {

    StringBuilder builder = new StringBuilder();
    builder.append("<" + getElementName() + " xmlns=\"" + getNamespace()
            + "\">");
    if (url != null) {
        builder.append("<url>").append(url).append("</url>");
    }
    if (description != null) {
        builder.append("<desc>").append(description).append("</desc>");
    }
    builder.append("</" + getElementName() + ">");
    return builder.toString();
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public String getUrl() {
    return url;
}

public void setUrl(String imageUrl) {
    this.url = imageUrl;
}

public static class FileExtensionProvider extends EmbeddedExtensionProvider {

    @Override
    protected PacketExtension createReturnExtension(String currentElement,
            String currentNamespace, Map<String, String> attributeMap,
            List<? extends PacketExtension> content) {

        System.out.println("EmbeddedExtensionProvider");
        return new FileExtension();
    }
}
}

注册提供商:

ProviderManager.getInstance().addExtensionProvider(
            FileExtension.ELEMENT, FileExtension.NAMESPACE,
            new FileExtension.FileExtensionProvider());

发送消息时:

FileExtension fileExt = new FileExtension("URL");
    fileExt.setDescription("Description");
    fileExt.setUrl("URL");

    msg.addExtension(fileExt);

收到消息后:

FileExtension fileExt = (FileExtension) message
                            .getExtension("jabber2:x2:oob2");

                    Log.i("File Extension description:", fileExt.toXML());

【问题讨论】:

    标签: android xmpp asmack


    【解决方案1】:

    以下是使用 aSmack 制作自定义扩展的完整解决方案:

    首先我必须创建 PacketExtension:

    public class ExtensionFile implements PacketExtension {
    
        public static final String ELEMENT = "file";
        public static final String NAMESPACE = "file:namespace";
    
        private String fileURL;
        private String fileSize;
    
        @Override
        public String getElementName() {
            return ELEMENT;
        }
    
        @Override
        public String getNamespace() {
            return NAMESPACE;
        }
    
        @Override
        public String toXML() {
    
            StringBuilder builder = new StringBuilder();
            builder.append("<" + getElementName() + " xmlns=\"" + getNamespace()
                + "\">");
            if (fileURL != null) {
                builder.append("<fileURL>").append(fileURL).append("</fileURL>");
            }
            if (fileSize != null) {
                builder.append("<fileSize>").append(fileSize).append("</fileSize>");
            }
            builder.append("</" + getElementName() + ">");
            return builder.toString();
        }
    
        public void setFileURL(String fileURL) {
            this.fileURL = fileURL;
        }
    
        public String getFileURL() {
            return fileURL;
        }
    
        public void setFileSize(String fileSize) {
            this.fileSize = fileSize;
        }
    
        public String getFileSize() {
            return fileSize;
        }
    }
    

    然后提供者解析这个数据包:

    public class ExtensionProviderFile implements PacketExtensionProvider {
    
    @Override
    public PacketExtension parseExtension(XmlPullParser parser)
            throws Exception {
    
        ExtensionFile fileExt = new ExtensionFile();
    
        int eventType = parser.next();
    
        while (eventType == XmlPullParser.START_TAG) {
    
            String name = parser.getName();
    
            switch (parser.getEventType()) {
    
                case XmlPullParser.START_TAG:
                    if (name.equals("fileURL")) {
    
                        fileExt.setFileURL(parser.nextText());
                    } else if (name.equals("fileSize")) {
    
                        fileExt.setFileSize(parser.nextText());
                    }
            }
    
            eventType = parser.next();
        }
    
        return fileExt;
    }
    }
    

    发送带有文件扩展名的消息:

    private void sendMessage(String recipient, String message){
    
        Message msg = new Message(recipient,Message.Type.chat);
        msg.setBody(message);
    
        //Create extension and set values
        ExtensionFile fileExt = new ExtensionFile();
        fileExt.setFileURL("http://www.example.com/upload_files/"+ abc.jpg);
        fileExt.setFileSize(fileSize);
    
        //add extension to message
        msg.addExtension(fileExt);
    
        //send message
        xmppConnection.sendPacket(msg);
    }
    

    要接收此消息,请实现 PacketListener 并覆盖 processPacket()

    @Override
    public void processPacket(Packet packet) {
    
        Message message = (Message) packet;
    
        //Get extension from message
        ExtensionFile extFile = (ExtensionFile) message
                        .getExtension("file:namespace");
    
        if (extFile != null) {
    
            //Get values from extension
            String filePath = extFile.getFileURL();
            String fileSize = extFile.getFileSize();
    
            System.out.println("Message :" + message.getBody() + " File url:" + filePath + " File size:" + fileSize);
        }
    }
    

    并在连接到 xmpp 服务器之前添加此提供:

    ProviderManager.getInstance().addExtensionProvider(
                ExtensionFile.ELEMENT, ExtensionFile.NAMESPACE,
                new ExtensionProviderFile());
    

    【讨论】:

    • 需要在 toXml() 方法中对 XML 进行转义。
    • @Flow 不一定需要。 toXml() 可用于查看 xml 格式的消息。 ProviderManager 解析 ExtensionFile
    • 您必须始终为 XML 转义字符串。例如 fileURL 可能包含需要转义的字符。
    • @Flow 我认为这就是 ExtensionProviderFile 在这种情况下所做的。
    • 不,提供者负责反序列化。 toXml() 序列化一个节。
    【解决方案2】:

    在最新版本的 Smack 4.1.7 中,删除了 PacketExtensionProvider (see this)。所以 ExtensionProviderFile 可以在扩展 ExtensionElementProvider 之后创建。请检查以下代码 -

    public class ExtensionProviderFile extends ExtensionElementProvider {
    
        @Override
        public Element parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException, SmackException {
    
            ChatExtension extensionFile = new ChatExtension();
    
            int eventType = parser.next();
    
            while (eventType == XmlPullParser.START_TAG){
                String name = parser.getName();
    
                switch (parser.getEventType()) {
    
                    case XmlPullParser.START_TAG:
    
                        if (name.equals("fileName")) {
                            extensionFile.setFileName(parser.nextText());
                        }
    
                        else if (name.equals("fullName")) {
                            extensionFile.setFullName(parser.nextText());
                        }
    
                }
    
                eventType = parser.next();
            }
    
            return extensionFile;
        }
    }
    

    希望这会对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-13
      • 1970-01-01
      • 2017-01-28
      相关资源
      最近更新 更多