打字状态 Smack 4.1 [英] Typing Status Smack 4.1

查看:30
本文介绍了打字状态 Smack 4.1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿,我正在尝试在其他人开始写作时获取打字状态,即使它返回一条带有状态作为消息的空消息,但它来自 proccessMessage 方法.它不应该在 stateChanged 中返回吗?我还没有启用任何 PacketProvider,我是否必须这样做才能在 stateChanged 方法中返回?我将不胜感激.

Hey I am trying to get typing status when the other person starts writing even though it is returning an empty message with the state as a message but it is coming from proccessMessage method. Shouldn't it be returned in the stateChanged? I haven't enabled any PacketProvider though, Do i have to do it so this would be returned in the stateChanged method? I would appreciate any help.

   newChat = chatmanager.createChat(contactUsername + sc.DOMAIN, new ChatStateListener() {
        @Override
        public void stateChanged(Chat chat, ChatState state) {
            if (ChatState.composing.equals(state)) {
               Log.d("Chat State",chat.getParticipant() + " is typing..");
            } else if (ChatState.gone.equals(state)) {
               Log.d("Chat State",chat.getParticipant() + " has left the conversation.");
            } else {
             Log.d("Chat State",chat.getParticipant() + ": " + state.name());
            }
        }

        @Override
        public void processMessage(Chat chat, Message message) {
            System.out.println("Received message: " + message);
        }
   });

日志:

06-15 14:28:47.679    9949-9983/com.example.example I/System.out﹕ Received message: <message to='+931111111111@example.com' from='+930000000000@example.com/Spark 2.6.3' id='AUJG0-42' type='chat'><thread>097uC9</thread><inactive xmlns='http://jabber.org/protocol/chatstates'/></message>

推荐答案

这是一个通用的答案,可能会有更好的答案,但这肯定有效,它可能包含您已经知道的内容,但我想它不能受伤了.

This is a general answer, there might be better ones, but this works for sure, it might contain stuff you already know, but I guess it can't hurt.

基本假设 - composing 消息是正文为空的消息,并且整个消息的 xml 包含一个 ChatState 标记,其中一个 active, compose、paused、inactive、gone 值,你要找的是composing,它的对应物是paused.

Base assumption - composing messages are messages where the body is null, and the xml of the whole message contains a ChatState tag with one of active, composing, paused, inactive, gone values, and what you're looking for is composing, and it's counterpart, paused.

话虽如此,在接收组件上,您需要这样的东西(根据您的需要修改它):

That being said, on the receiving component you need something like this (modify it to your needs):

yourComponent.addMessageListener(new PacketListener()
            {
                @Override
                public void processPacket(Packet packet) throws NotConnectedException
                {
                    try
                    {
                        Message msg = (Message) packet;
                        String msg_xml = msg.toXML().toString();

                        if (null != msg.getBody())
                        {
                          //handle as a regular chat message....
                        }
                        else
                        {
                            if (msg_xml.contains(ChatState.composing.toString()))
                            {
                              //handle is-typing, probably some indication on screen
                            }
                            else if (msg_xml.contains(ChatState.paused.toString()))
                            {
                             // handle "stopped typing" 
                            }
                       }
                    }
                    catch (Exception e)
                    {
                     e.printStackTrace();
                    }
               }
            });

您的日志消息显示您收到了一个 inactive 消息,因此对于初学者,请尝试过滤所有消息,并找到您要查找的内容的模式,看看是否发送方甚至发送您需要的东西.

Your log message shows you got an inactive message, so for starters, try filtering all the messages, and find the pattern of what your looking for, to see if the sending side is even sending what you need.

一个很好的理解方法是使用您知道的另一个客户端来发送撰写状态,并查看您在过滤器中得到的内容(例如,在 linux 下,您可以对发送方使用 pidgin 或 empathy).

A good way to understand would be to use another client that you know for a fact that's sending the composing state, and see what you get in your filter (e.g. under linux you could use pidgin or empathy for the sending side).

编辑 2:

根据要求,我还添加了一些发送端组件以获得更完整的图片,同样,这是一个供参考的通用示例,可​​以进行优化和更改.

As per requested, I'm also adding some of the sending-side components for a more complete picture, again, this is a general example for reference purpose, and could be optimized and changed.

首先,实现一个自定义 EditText,它实现了一个带有小线程的 TextWatcher,该线程以您希望从上次文本更改到说我停止打字"的延迟触发,根据需要设置间隔:

First, implement a custom EditText that implements a TextWatcher with a small thread that fires with the delay you want from the last text change to say "I stopped typing", set your interval as you want:

public class MyIsTypingEditText extends EditText implements TextWatcher
{
  private static final int TypingInterval = 800;

  //your listener interface that you implement anonymously from the Activity
  public interface OnTypingModified
  {
      public void onIsTypingModified(EditText view, boolean isTyping);
  }

  private OnTypingModified typingChangedListener;

  //members you would need for the small thread that declares that you have stopped typing
  private boolean currentTypingState = false;
  private Handler handler = new Handler();
  private Runnable stoppedTypingNotifier = new Runnable()
  {
      @Override
      public void run() 
      {
          //part A of the magic...
          if(null != typingChangedListener)
          {
            typingChangedListener.onIsTypingModified(MyIsTypingEditText.this, false);
            currentTypingState = false;
          }
      }
   };

  public MyIsTypingEditText(Context context)
  {
      super(context);
      this.addTextChangedListener(this);
  }

  public void setOnTypingModified(OnTypingModified typingChangedListener)
  {
      this.typingChangedListener = typingChangedListener;
  }

  @Override
  public void afterTextChanged(Editable s)
  {
      //part B of the magic...
      if(null != typingChangedListener)
      {
          if(!currentTypingState)
          {
              typingChangedListener.onIsTypingModified(this, true);
              currentTypingState = true;
          }

          handler.removeCallbacks(stoppedTypingNotifier);
          handler.postDelayed(stoppedTypingNotifier, TypingInterval);
      }
  }

  @Override
  public void beforeTextChanged(CharSequence s, int start, int count,   int after) { }


  @Override
  public void onTextChanged(CharSequence text, int start,   int before, int after) { }

  }

接下来,在处理您聊天的活动中,添加一个新的匿名接口并使用您的状态更改消息发送方法调用实现它的回调,这部分 C 是魔法,因为这将发送与 TextWatcher 对应的状态小线程:

Next, in the activity that handles your chat, add a new anonymous interface and implement it's callback with your state-changing-message sending method call, this part C of the magic, as this will send your state corresponding to the TextWatcher mini-thread:

    yourIsTypingEditText.setOnTypingModified(new MyIsTypingEditText.OnTypingModified()
    {
        @Override
        public void onIsTypingModified(EditText view, boolean isTyping)
        {
            XmppConnectionClass.Composing composing = (isTyping) ? XmppConnectionClass.Composing.isTyping : XmppConnectionClass.Composing.stoppedTyping;

            XmppConnectionClass.getInstance().sendIsComposing(composing);
        }
    });

最后但并非最不重要的是,在您的连接处理程序类中,您应该具有以下内容:

And last but not least, in your connection handler class you should have the following:

//.... other stuff

//a mini enum Composing class for state setting
public enum Composing
{
  private ChatState state;

  Composing(ChatState state)
  {
      this.state = state;
  }

  isTyping(ChatState.composing), stoppedTyping(ChatState.paused);

    public ChatState getState()
    {
        return (state);
    }
}

 //.... other stuff

 public boolean sendIsComposing(Composing composing)
{
    try
    {
        Message msg = new Message(...);

        //other stuff...

        msg.setBody(null);
        msg.addExtension(new ChatStateExtension(composing.getState()));

        //other stuff...

        this.sendMessage(msg);
        return (true);
    }
    catch (Exception e)
    {
        e.printStackTrace();
        return (false);
    }
}

希望这会有所帮助.

这篇关于打字状态 Smack 4.1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆