Android Smack 4.1禁用自动收据

Android Smack 4.1禁用自动收据,android,xmpp,smack,Android,Xmpp,Smack,我刚从已贬值的asmack切换到Smack 4.1。Smack 4.1自动发送带有错误id的收据,这在我的情况下导致了异常 Smack 4.1随收据附上2个不同的id 这是收到的聊天信息 RECV (0): <message from='***' to='***' xml:lang='en' id='65' kind='0' type='chat'><body>vhh</body><request xmlns='urn:xmpp:receipts'/&g

我刚从已贬值的asmack切换到Smack 4.1。Smack 4.1自动发送带有错误id的收据,这在我的情况下导致了异常

Smack 4.1随收据附上2个不同的id

这是收到的聊天信息

RECV (0): <message from='***' to='***' xml:lang='en' id='65' kind='0' type='chat'><body>vhh</body><request xmlns='urn:xmpp:receipts'/></message>
RECV(0):甚高频
以下是Smack 4.1为响应聊天信息而生成的收到的回执

SENT (0): <message to='***' id='roZ7C-32' type='chat'><received xmlns='urn:xmpp:receipts' id='65'/></message>
已发送(0):
Smack 4.1附加了两个不同的id,分别带有收到的收据id='roZ7C-32'id='65'

我的问题是:

  • 如何使这两个ID相同
  • 如何禁用收据以便生成自定义收据

  • 对于第一个问题,要获取发送消息的ID,代码为:

    Message ms = new Message();
    ms.addBody("EN", Messegeforsend);
    DeliveryReceiptRequest.addTo(ms); //tells that you will need delivery for this message
    String send_message_id= ms.getStanzaId();
    
    您可以获取已发送邮件的ID,该ID与已发送邮件的ID相同:

    deliveryReceiptManager = DeliveryReceiptManager.getInstanceFor(connection);
    deliveryReceiptManager.addReceiptReceivedListener(new ReceiptReceivedListener() {
    
                @Override
                public void onReceiptReceived(String arg0, String arg1, String arg2,Stanza arg3) {
                    String delivered_message_id = arg2;
    }
    
    }))

    send_message_id将完全等于delivered_message_id,因此您将知道已传递了哪条消息

    SMACK 4.1.0消息接收侦听器编写以下代码


    您可以禁用此功能的方法只是在发送邮件时不向邮件添加回执:

    最重要的方法是

    processPacketExtension

    //在方法中创建消息
    公共发送消息(Jid to,字符串正文){
    消息消息=消息(收件人,正文);
    //创建deliveryID并将其保存到SQLite数据库
    deliveryID=DeliveryReceiptRequest.addTo(msg);
    getInstanceFor(连接).chatWith(jid).send(消息);
    }
    //声明您的节侦听器
    私有MessagePacketListener MessagePacketListener;
    //在你的同僚中
    messagePacketListener=新messagePacketListener(上下文);
    //然后在您的登录方法中,像这样注册您的节侦听器
    public void login()引发异常,xmppstringpreception{
    connect();
    试一试{
    如果(!con.isAuthenticated()){
    ....
    con.addSyncStanzaListener(messagePacketListener,新的节类型过滤器(Message.class));
    ....
    }
    }捕获(例外e){
    ....
    }
    }
    //StanzaListener,用于解析传入消息,如果没有正文,则为送达回执
    //现在您有了处理传入消息的MessagePacketListener
    公共类MessagePacketListener实现StanzaListener{
    私人语境;
    MessagePacketListener(上下文){
    this.context=上下文;
    }    
    @凌驾
    公共无效处理节(节数据包){
    消息消息=(消息)数据包;
    //有正文的消息
    如果(msg.getBodies().size()>0){
    //短信
    //对消息msg.getBody()执行一些操作
    }
    否则{
    //这必须是类似送货收据或聊天状态消息,并获得您的送货ID
    processPacketExtension(msg);
    }
    }
    //接收数据包传递的processPacketExtension方法
    私有void processPacketExtension(消息msg){
    集合扩展=msg.getExtensions();
    if(扩展名!=null){
    迭代器迭代器=extensions.Iterator();
    if(iterator.hasNext()){
    ExtensionElement extension=iterator.next();
    if(DeliveryReceive的扩展实例){
    //用deliveryID做某事
    字符串deliveryID=((DeliveryReceipt)扩展名).getId();
    }
    }
    }
    }
    }
    
    Smack的行为在我看来是正确的。如果这会导致收货方出现异常,那么这是一个错误。为什么Smack会在一条聊天信息上附加两个不同的id和一张收据?涉及到两个消息节,每个节都有自己的唯一id。第一个id为“65”的消息节Smack确认已将包含
    的信息节(id“roZ7C-32”)发送回“65”的发件人。我是否可以让Smack发送两个节的id 65而不是roZ7C-32No,这是不可能的,也不是一个好主意。
    try {
                    Message ms = new Message();
                    ms.addBody("EN", "deleriyed");
                    ms.setTo(message.getFrom());
                    ms.setStanzaId(message.getStanzaId());
                    DeliveryReceiptRequest.addTo(ms);
                    connection.sendStanza(ms);
                } catch (NotConnectedException e) {
                    e.printStackTrace();
                }
    
    //Creating message in your method
    public sendMessage(Jid to, String body){
        Message msg = Message(to, body);
        //Create and save your deliveryID to SQLite database
        deliveryID = DeliveryReceiptRequest.addTo(msg);
        ChatManager.getInstanceFor(connection).chatWith(jid).send(msg);
    }
    
    //Declare your stanza listener
    private MessagePacketListener messagePacketListener;
    //In your cotnructor   
    messagePacketListener = new MessagePacketListener(context);
    
    //Then in your login method register your stanza listener like this
    public void login() throws SmackInvocationException, XmppStringprepException {
            connect();
            try {
                if (!con.isAuthenticated()) {
                    ....
                    con.addSyncStanzaListener(messagePacketListener, new StanzaTypeFilter(Message.class));
                    ....
                    }
            } catch(Exception e) {
                        ....
                }
            }
    
    
    
    //Your StanzaListener where you parse your incoming message and if it is without body it is Delivery receipt
    //Now you have your MessagePacketListener that process the incoming messages
    
    public class MessagePacketListener implements StanzaListener{
        private Context context;
    
        MessagePacketListener(Context context) {
            this.context = context;
        }    
        @Override
        public void processStanza(Stanza packet) {
            Message msg = (Message)packet;
    
            //Message that have body
            if(msg.getBodies().size() > 0){
                //Text message
                //Do something with message msg.getBody()
            }
            else{
                //This must be sth like delivery receipt or Chat state msg and get your deliveryID
                processPacketExtension(msg);
            }
        }
    
        //processPacketExtension method that receive packet delivery ectension
        private void processPacketExtension(Message msg) {
            Collection<ExtensionElement> extensions = msg.getExtensions();
            if (extensions != null) {
                Iterator<ExtensionElement> iterator = extensions.iterator();
                if (iterator.hasNext()) {
                    ExtensionElement extension = iterator.next();                
                    if(extension instanceof DeliveryReceipt){
                        //Do sth with deliveryID
                        String deliveryID = ((DeliveryReceipt) extension).getId();
                    }
                }
            }
        }
    }