如何在 xmpp android 中的多用户聊天/群聊和一对一聊天中发送撰写/正在输入(聊天状态)事件?
How to send composing / is typing (Chat states) event in Multiuser chat / Group chat & One to One chat in xmpp android?
我想在 xmpp 中的群组(多用户)聊天中发送撰写事件,我正在使用 asmack 库,我在一对一聊天中完成了相同的功能。
我正在使用以下代码:
mMessageEventManager = new MessageEventManager(XMPPConnectApplication.getInstance().getXmppConnection());
mMessageEventManager.addMessageEventNotificationListener(new MessageEventNotificationListener() {
@Override
public void offlineNotification(String arg0, String arg1) {
}
@Override
public void displayedNotification(String arg0, String arg1) {
}
@Override
public void deliveredNotification(String arg0, String arg1) {
}
@Override
public void composingNotification(String from, String to) {
Log.e("Receiver-composingNotification",from + " is started typing......"+to);
}
@Override
public void cancelledNotification(String from, String to) {
Log.e("Receiver-cancelledNotification",from + " is stopped typing......"+to);
}
});
如果您对此有任何想法,请告诉我。
如有任何帮助,我们将不胜感激。
是的,我有这个想法,而且我在 1 周前就完成了。
我已经使用 MessageEventManager 来管理聊天状态。
private MessageEventManager mMessageEventManager;
为聊天状态接收监听器添加此方法:
private void chatStateRecognizer(){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
mMessageEventManager = new MessageEventManager(mXmppConnection);
mMessageEventManager.addMessageEventNotificationListener(new MessageEventNotificationListener() {
@Override
public void offlineNotification(String arg0, String arg1) {
}
@Override
public void displayedNotification(String arg0, String arg1) {
}
@Override
public void deliveredNotification(String from, String arg1) {
}
@Override
public void composingNotification(String from, String to) {
Log.i("Receiver:Compose state",from + " is started typing......"+to);
}
@Override
public void cancelledNotification(String from, String to) {
Log.i("Receiver:Stop state",from + " is stopped typing......"+to);
}
});
}
});
thread.start();
}
创建一个模型 class 名称为 GroupInfoModel.java:
public class GroupInfoModel implements Comparable<GroupInfoModel>, Serializable{
private static final long serialVersionUID = 1L;
private String memberId = "", memberName = "";
private boolean isAdmin;
public String getMemberId() {
return memberId;
}
public void setMemberId(String memberId) {
this.memberId = memberId;
}
public String getMemberName() {
return memberName;
}
public void setMemberName(String memberName) {
this.memberName = memberName;
}
public boolean isAdmin() {
return isAdmin;
}
public void setAdmin(boolean isAdmin) {
this.isAdmin = isAdmin;
}
@Override
public int compareTo(GroupInfoModel another) {
return getMemberName().compareTo(another.getMemberName());
}
}
现在取 ArrayList of GroupInfoModel.java class:
private ArrayList<GroupInfoModel> groupDetailsList = new ArrayList<GroupInfoModel>();
private boolean isComposingStarted;
on onCreate() of Activity / Fragment:
groupDetailsList.clear();
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(mXmppConnection);
DiscoverItems items = discoManager.discoverItems(mRoomId);
for (Iterator<Item> it = items.getItems(); it.hasNext();) {
DiscoverItems.Item item = (DiscoverItems.Item) it.next();
String occupant = item.getEntityID();
occupant = occupant.split("/")[1];
GroupInfoModel groupInfoModel = new GroupInfoModel();
groupInfoModel.setAdmin(false);
groupInfoModel.setMemberId(occupant+"@"+mServiceNameHere);
groupInfoModel.setMemberName(occupant);
groupDetailsList.add(groupInfoModel);
}
现在在 Compose Message 的 EditText 上添加 TextWatcher(聊天视图) 屏幕:
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(s.toString().length()==1&&!isComposingStarted){
isComposingStarted = true;
if(chatType.equals("OneToOneChat")){
mMessageEventManager.sendComposingNotification(myJabberId, friendJabberId);
}else if(chatType.equals("GroupChat")){
for (int i = 0; i < groupDetailsList.size(); i++) {
if(!groupDetailsList.get(i).getMemberId().contains(myJabberId)){
mMessageEventManager.sendComposingNotification(groupDetailsList.get(i).getMemberId(), roomId);
}
}
}
}else if(s.toString().length()==0){
isComposingStarted = false;
if(chatType.equals("OneToOneChat")){
mMessageEventManager.sendCancelledNotification(myJabberId, friendJabberId);
}else if(chatType.equals("GroupChat")){
for (int i = 0; i < groupDetailsList.size(); i++) {
if(!groupDetailsList.get(i).getMemberId().contains(myJabberId)){
mMessageEventManager.sendCancelledNotification(groupDetailsList.get(i).getMemberId(), roomId);
}
}
}
}
}
我强烈推荐在Application中使用以上代码class,您可以根据需要修改方法。
完成.
// send multi user chat typing status
public static void sendMUCTypingStatus(ChatState state)
{
// check if you are connected to group
if(multiUserChat != null)
{
try{
// create packet
Message statusPacket = new Message();
// set body to null
statusPacket.setBody(null);
// set packet type to group chat
statusPacket.setType(Message.Type.groupchat);
// set subject to null
statusPacket.setSubject(null);
// set to the group name
statusPacket.setTo(multiUserChat.getRoom());
// set from my current jis example : me@domain.com
statusPacket.setFrom(new MyPrefrence(XmppBase.context).getUsername());
// get the chat state extension and pass our state
ChatStateExtension extension = new ChatStateExtension(state);
// add the extention to our packet
statusPacket.addExtension(extension);
// get the connection and send the packet
Utils.getConnection().sendStanza(statusPacket);
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
}
}
用法:
sendMucTypingStatus(ChatState.composing);
用RxJava and Jake Wharton's RxBinding,做起来很简单:
RxTextView.afterTextChangeEvents(editText)
.observeOn(Schedulers.io())
.skip(1)
.map({ input ->
// FIRE ChatState.composing EVENT HERE
input // just returning the argument here
})
.debounce(2, TimeUnit.SECONDS)
.observeOn(Schedulers.io())
.subscribe {
// FIRE ChatState.active EVENT HERE
}
请记住,我们必须编写代码通过 smack stanzaListener 捕获这些事件,并相应地在 UI 上显示!
代码是用 Kotlin 编写的,但相当简单。
我想在 xmpp 中的群组(多用户)聊天中发送撰写事件,我正在使用 asmack 库,我在一对一聊天中完成了相同的功能。
我正在使用以下代码:
mMessageEventManager = new MessageEventManager(XMPPConnectApplication.getInstance().getXmppConnection());
mMessageEventManager.addMessageEventNotificationListener(new MessageEventNotificationListener() {
@Override
public void offlineNotification(String arg0, String arg1) {
}
@Override
public void displayedNotification(String arg0, String arg1) {
}
@Override
public void deliveredNotification(String arg0, String arg1) {
}
@Override
public void composingNotification(String from, String to) {
Log.e("Receiver-composingNotification",from + " is started typing......"+to);
}
@Override
public void cancelledNotification(String from, String to) {
Log.e("Receiver-cancelledNotification",from + " is stopped typing......"+to);
}
});
如果您对此有任何想法,请告诉我。
如有任何帮助,我们将不胜感激。
是的,我有这个想法,而且我在 1 周前就完成了。
我已经使用 MessageEventManager 来管理聊天状态。
private MessageEventManager mMessageEventManager;
为聊天状态接收监听器添加此方法:
private void chatStateRecognizer(){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
mMessageEventManager = new MessageEventManager(mXmppConnection);
mMessageEventManager.addMessageEventNotificationListener(new MessageEventNotificationListener() {
@Override
public void offlineNotification(String arg0, String arg1) {
}
@Override
public void displayedNotification(String arg0, String arg1) {
}
@Override
public void deliveredNotification(String from, String arg1) {
}
@Override
public void composingNotification(String from, String to) {
Log.i("Receiver:Compose state",from + " is started typing......"+to);
}
@Override
public void cancelledNotification(String from, String to) {
Log.i("Receiver:Stop state",from + " is stopped typing......"+to);
}
});
}
});
thread.start();
}
创建一个模型 class 名称为 GroupInfoModel.java:
public class GroupInfoModel implements Comparable<GroupInfoModel>, Serializable{
private static final long serialVersionUID = 1L;
private String memberId = "", memberName = "";
private boolean isAdmin;
public String getMemberId() {
return memberId;
}
public void setMemberId(String memberId) {
this.memberId = memberId;
}
public String getMemberName() {
return memberName;
}
public void setMemberName(String memberName) {
this.memberName = memberName;
}
public boolean isAdmin() {
return isAdmin;
}
public void setAdmin(boolean isAdmin) {
this.isAdmin = isAdmin;
}
@Override
public int compareTo(GroupInfoModel another) {
return getMemberName().compareTo(another.getMemberName());
}
}
现在取 ArrayList of GroupInfoModel.java class:
private ArrayList<GroupInfoModel> groupDetailsList = new ArrayList<GroupInfoModel>();
private boolean isComposingStarted;
on onCreate() of Activity / Fragment:
groupDetailsList.clear();
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(mXmppConnection);
DiscoverItems items = discoManager.discoverItems(mRoomId);
for (Iterator<Item> it = items.getItems(); it.hasNext();) {
DiscoverItems.Item item = (DiscoverItems.Item) it.next();
String occupant = item.getEntityID();
occupant = occupant.split("/")[1];
GroupInfoModel groupInfoModel = new GroupInfoModel();
groupInfoModel.setAdmin(false);
groupInfoModel.setMemberId(occupant+"@"+mServiceNameHere);
groupInfoModel.setMemberName(occupant);
groupDetailsList.add(groupInfoModel);
}
现在在 Compose Message 的 EditText 上添加 TextWatcher(聊天视图) 屏幕:
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(s.toString().length()==1&&!isComposingStarted){
isComposingStarted = true;
if(chatType.equals("OneToOneChat")){
mMessageEventManager.sendComposingNotification(myJabberId, friendJabberId);
}else if(chatType.equals("GroupChat")){
for (int i = 0; i < groupDetailsList.size(); i++) {
if(!groupDetailsList.get(i).getMemberId().contains(myJabberId)){
mMessageEventManager.sendComposingNotification(groupDetailsList.get(i).getMemberId(), roomId);
}
}
}
}else if(s.toString().length()==0){
isComposingStarted = false;
if(chatType.equals("OneToOneChat")){
mMessageEventManager.sendCancelledNotification(myJabberId, friendJabberId);
}else if(chatType.equals("GroupChat")){
for (int i = 0; i < groupDetailsList.size(); i++) {
if(!groupDetailsList.get(i).getMemberId().contains(myJabberId)){
mMessageEventManager.sendCancelledNotification(groupDetailsList.get(i).getMemberId(), roomId);
}
}
}
}
}
我强烈推荐在Application中使用以上代码class,您可以根据需要修改方法。
完成.
// send multi user chat typing status
public static void sendMUCTypingStatus(ChatState state)
{
// check if you are connected to group
if(multiUserChat != null)
{
try{
// create packet
Message statusPacket = new Message();
// set body to null
statusPacket.setBody(null);
// set packet type to group chat
statusPacket.setType(Message.Type.groupchat);
// set subject to null
statusPacket.setSubject(null);
// set to the group name
statusPacket.setTo(multiUserChat.getRoom());
// set from my current jis example : me@domain.com
statusPacket.setFrom(new MyPrefrence(XmppBase.context).getUsername());
// get the chat state extension and pass our state
ChatStateExtension extension = new ChatStateExtension(state);
// add the extention to our packet
statusPacket.addExtension(extension);
// get the connection and send the packet
Utils.getConnection().sendStanza(statusPacket);
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
}
}
用法:
sendMucTypingStatus(ChatState.composing);
用RxJava and Jake Wharton's RxBinding,做起来很简单:
RxTextView.afterTextChangeEvents(editText)
.observeOn(Schedulers.io())
.skip(1)
.map({ input ->
// FIRE ChatState.composing EVENT HERE
input // just returning the argument here
})
.debounce(2, TimeUnit.SECONDS)
.observeOn(Schedulers.io())
.subscribe {
// FIRE ChatState.active EVENT HERE
}
请记住,我们必须编写代码通过 smack stanzaListener 捕获这些事件,并相应地在 UI 上显示!
代码是用 Kotlin 编写的,但相当简单。