如何使用 Smack 在 XMPP openfire 中了解打字状态
Posted
技术标签:
【中文标题】如何使用 Smack 在 XMPP openfire 中了解打字状态【英文标题】:How to know Typing Status in XMPP openfire using Smack 【发布时间】:2013-08-28 11:53:12 【问题描述】:我正在使用 Openfire XMPP 服务器开发聊天应用程序。我可以在两个用户之间进行文字聊天。但是我想知道有人在输入消息时的输入状态。所以我创建了一个类:-
public class typingStatus implements ChatStateListener
@Override
public void processMessage(Chat arg0, Message arg1)
// TODO Auto-generated method stub
@Override
public void stateChanged(Chat arg0, ChatState arg1)
// TODO Auto-generated method stub
System.out.println(arg0.getParticipant() + " is " + arg1.name());
但我很困惑,所以它将如何工作?我知道我需要一个可以在侦听器中使用的数据包。但是我找不到那个包。
请任何人建议,它将如何工作?
还有 Smack 和 asmack 有什么区别?
谢谢!
【问题讨论】:
请在 *** 中检查这个问题:***.com/questions/21154833/… 【参考方案1】:要启用ChatStateListener
,您需要创建一个自定义MessageListener
类
public class MessageListenerImpl implements MessageListener,ChatStateListener
@Override
public void processMessage(Chat arg0, Message arg1)
System.out.println("Received message: " + arg1);
@Override
public void stateChanged(Chat arg0, ChatState arg1)
if (ChatState.composing.equals(arg1))
Log.d("Chat State",arg0.getParticipant() + " is typing..");
else if (ChatState.gone.equals(arg1))
Log.d("Chat State",arg0.getParticipant() + " has left the conversation.");
else
Log.d("Chat State",arg0.getParticipant() + ": " + arg1.name());
然后你创建MessageListener
对象
MessageListener messageListener = new MessageListenerImpl();
然后在创建聊天方法中传递这个
Chat newChat = chatmanager.createChat(jabber_id_of_friend, messageListener);
Smack 和 asmack 有什么区别? Check This
【讨论】:
谢谢你。看起来不错,给了我解决方案。我会检查的。 no userID 是其他参与者的 jid,而不是登录者 谢谢你。如果你有一点时间。也请检查***.com/questions/18437329/… 要处理消息事件,请查看igniterealtime.org/builds/smack/docs/latest/documentation/… 我检查了但没有得到 stateChanged。请建议【参考方案2】:我终于找到了解决方案。我需要使用聊天监听器和聊天管理器,还需要使用内置的 sendcomposingnotification 功能。无需为此使用 Messageeventrequestlistener 接口或任何其他自定义类。我添加了以下几行,
connection.getChatManager().addChatListener(new ChatManagerListener()
@Override
public void chatCreated(final Chat arg0, final boolean arg1)
// TODO Auto-generated method stub
arg0.addMessageListener(new MessageListener()
@Override
public void processMessage(Chat arg0, Message arg1)
// TODO Auto-generated method stub
Log.d("TYpe Stat",title[0] + " is typing......");
Toast.makeText(getApplicationContext(),title[0] + " is typing......",Toast.LENGTH_SHORT).show();
);
);
还需要像这样发送通知..
mem.sendComposingNotification(etRecipient.getText().toString(), message.getPacketID());
System.out.println("Sending notification");
其中 mem 是 MessageEventManger 的类型。 参考:http://www.igniterealtime.org/builds/smack/docs/latest/javadoc/org/jivesoftware/smackx/MessageEventManager.html
【讨论】:
嗨,我在上面试过了..但没有用!这是我的代码!任何帮助将不胜感激....... Message msg1 = new Message(to, Message.Type.chat); msg1.setFrom("user1@192.168.0.98"); // 我的 id MessageEventManager event=new MessageEventManager(connection); //recipient id event.sendComposingNotification("tech1@192.168.0.98",msg1.getPacketId()); @Aneez,您需要处理在processMessage()
中收到的消息,因为它接收所有传入的数据包,而不仅仅是typing
状态。它可能是暂停,离线/在线状态包,或消息..所以尝试处理它然后处理..
嗨。我尝试了同样的方法,但它对我不起作用..它既不发送组合通知也不接收它。在接收和从 ios 接收时给我 null。帮我找出这个。谢谢。
仅供参考:从***.com/questions/21154833/…合并【参考方案3】:
您或您使用的其他 xmpp 客户端应该发送聊天状态,以便您可以捕获状态。
像这样;
try
ChatStateManager.getInstance(GlobalVariables.xmppManager.connection).setCurrentState(ChatState.composing, chat);
catch (XMPPException e)
e.printStackTrace();
或
try
ChatStateManager.getInstance(GlobalVariables.xmppManager.connection).setCurrentState(ChatState.gone, chat);
catch (XMPPException e)
e.printStackTrace();
【讨论】:
可能你的服务器应用不支持它。 您的意思是说我们的服务器没有为此配置?但它在 ios 到 ios 上运行良好。我在 EditText 的 textChangeListner 上写下这一行。聊天对象是 chatmanager = connection.getChatManager();聊天聊天 = chatmanager.createChat("user@", listner);即使我从 ios processMessage 收到撰写状态,也给我 null。请帮助我找到发送和接收的解决方案。附言我正在使用 asmack 库 仅供参考:从***.com/questions/22225394/…合并 这需要在editext text text change listener上完成。对吧?【参考方案4】:ChatManager chatManager = ChatManager.getInstanceFor(connection);
Chat chat= chatManager.createChat(to, new ChatStateListener()
@Override
public void stateChanged(Chat chat, ChatState state)
switch (state)
case active:
Log.d("state","active");
break;
case composing:
Log.d("state","composing");
break;
case paused:
Log.d("state","paused");
break;
case inactive:
Log.d("state","inactive");
break;
case gone:
Log.d("state","gone");
break;
@Override
public void processMessage(Chat chat, Message message)
Log.d("processMessage","processMessage");
);
使用此代码。希望如此工作
【讨论】:
你好,Ahesanali Momin,你能告诉我你最后的确切情况吗?你在 XMPP 中遇到了什么样的错误。欲了解更多信息,请通过 skype@piyush.gupta326 给我发消息。然后我们可以讨论更多,你的问题,希望能达到成功点。 我没有收到任何错误,但是当我开始打字时,代码没有进入任何状态,我的意思是 stateChangeListener 没有被调用。 嘿伙计,你读过这个文档吗xmpp.org/extensions/xep-0085.html 这完全是理论上的,目前还没有什么有趣的,因为使用聊天客户端大部分事情都很清楚。 我的意思是,请阅读该链接中的文档。我希望你能在那里找到解决方案。否则我们可以在这里讨论。【参考方案5】:我正在使用聊天状态监听器:
Chat chat = chatManager.createChat(jid,
new ChatStateChangedListener());
将 chatstatelistener 与上面的每个 jid 绑定,然后:
public class ChatStateChangedListener implements ChatStateListener
public ChatStateChangedListener()
printLog("Chat State Changed Listner Constructor");
@Override
public void processMessage(Chat arg0, Message arg1)
@Override
public void stateChanged(Chat chat, ChatState state)
if (state.toString().equals(ChatState.composing.toString()))
tvLastSeen.setText("Typing...");
else if (state.toString().equals(ChatState.paused.toString()))
tvLastSeen.setText("paused...");
else
tvLastSeen.setText("nothing");
【讨论】:
仅供参考:从***.com/questions/21154833/…合并【参考方案6】:在 MMessageListener 类上创建以侦听传入消息
私有类MMessageListener实现MessageListener、ChatStateListener
public MMessageListener(Context contxt)
@Override
public void stateChanged(Chat chat, ChatState chatState)
mStatus = "Online";
if (ChatState.composing.equals(chatState))
mStatus = chat.getParticipant() + " is typing..";
Log.d("Chat State", chat.getParticipant() + " is typing..");
else if (ChatState.gone.equals(chatState))
Log.d("Chat State", chat.getParticipant() + " has left the conversation.");
mStatus = chat.getParticipant() + " has left the conversation.";
else if (ChatState.paused.equals(chatState))
Log.d("Chat State", chat.getParticipant() + ": " + chatState.name());
mStatus = "Paused";
else if (ChatState.active.equals(chatState))
mStatus = "Online";
// do whatever you want to do once you receive status
@Override
public void processMessage(Message message)
@Override
public void processMessage(Chat chat, Message message)
将侦听器添加到您的聊天对象
Chat Mychat = ChatManager.getInstanceFor(connection).createChat( "user2@localhost"), mMessageListener);
在编辑文本文本更改时向接收用户发送状态
ChatStateManager.getInstance(connection).setCurrentState(ChatState.composing, Mychat);
这对我来说很好。
【讨论】:
嗨,Dharmesh,我也做了同样的事情,但是在 processMessage 中编写状态消息时我总是得到空值。我的 EditText 文本更改方法是:newChat = chatmanager.createChat(send_to, messageListener); Message msg = new Message(send_to, Message.Type.chat); msg.setFrom(USERNAME_LOGIN+"@"+HOST_NAME); // 我的 id newChat.sendMessage(msg); ChatStateManager.getInstance(connection).setCurrentState(ChatState.composing, newChat);这也不会将状态发送给其他人。 仅供参考:从***.com/questions/21154833/…合并 如何检查用户是否已暂停或不再在编辑文本中输入?【参考方案7】:但是,您也可以从 ProcessPacket 获取它。 在那里你会得到一个 Message 对象,你可以从那里提取 xml 部分并处理它们是否包含特定的聊天状态。
Message message = (Message) packet;
String msg_xml = message.toXML().toString();
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"
else
// normal msg
现在按您的要求处理。
【讨论】:
【参考方案8】:只需在ChatManager
后添加ChatStateManager
即可:
chatManager = ChatManager.getInstanceFor(getXmpptcpConnection());
ChatStateManager.getInstance(getXmpptcpConnection());
那你需要在createChat(to,chatMesageListener)
期间加上ChatStateListener
:
chatManager.createChat(message.getTo(), chatMessageListener).sendMessage(message);
private ChatStateListener chatMessageListener = new ChatStateListener()
@Override
public void stateChanged(Chat chat, ChatState state)
//State Change composing,active,paused,gone,etc
Log.d(TAG, "ChatStateListener:::stateChanged -> " + chat.toString() + " \n -> " + state.toString());
@Override
public void processMessage(Chat chat, Message message)
//Incoming Message
Log.d(TAG, "ChatStateListener:::processMessage -> " + chat.toString() + " \n -> " + message.toString());
;
【讨论】:
仅供参考:从***.com/questions/22225394/…合并 下一次,也许只回答一个问题并标记其余问题,让我们知道它们是重复的;发布相同的答案 7 次实在是太过分了。以上是关于如何使用 Smack 在 XMPP openfire 中了解打字状态的主要内容,如果未能解决你的问题,请参考以下文章
使用 xmpp + smack + openfire 在 android 中阻止用户
我在使用 smack 4.2 Openfire 创建 XMPP 客户端时遇到问题
使用 Openfire 服务器和 XMPP(SMACK)客户端的 Android 聊天应用程序 [关闭]
Android 基于XMPP Smack openfire 开发的聊天室