如何在多用户聊天/群聊和&amp ;;中发送撰写/正在输入(聊天状态)事件在xmpp android中一对一聊天?

时间:2015-11-02 13:59:15

标签: android xmpp asmack multiuserchat groupchat

我希望在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);

                    }
                }); 

如果您对此有任何想法,请告诉我。

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:4)

是的,我对此有所了解,而且我在1周前做过。

enter image description here

我使用 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();
    }

使用 GroupInfoModel.java 创建一个Model类名:

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());
    }
}

现在使用 GroupInfoModel.java 类的 ArrayList

private ArrayList<GroupInfoModel> groupDetailsList = new ArrayList<GroupInfoModel>();

private boolean isComposingStarted;

onCreate() 活动 / 片段

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);
    }

现在在撰写邮件聊天视图)屏幕的 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); 
               }
            }
        }
    }
}

强烈推荐应用 中使用上述代码,您可以根据需要修改方法。

完成

答案 1 :(得分:2)

// 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);

请注意:Quick overview of using

答案 2 :(得分:0)

使用 RxJava 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编写的,但它非常直接。