Rons Jackos Rons Jackos - 2 months ago 22
Android Question

How to send composing / is typing (Chat states) event in Multiuser chat / Group chat & One to One chat in xmpp android?

I want send composing event in Group (Multiuser) chat in xmpp, I am using asmack library, I have done same functionality with One to One chat.

I am using below code:

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

}
});


Please let me know if you have any idea for the same.

Any help will be appreciated.

Answer

Yes, I have idea about it and I have done just before 1 week.

enter image description here

I have used MessageEventManager to manage Chat States.

private MessageEventManager mMessageEventManager;

Add this method for Chat State Receiving Listener:

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

Create one Model class name with 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());
    }
}

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

Now add TextWatcher on your EditText of Compose Message (Chat view) screen:

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

I strongly recommended that use above code in Application class, you can modify methods as your requirements.

Done.