How to know Typing Status in XMPP openfire using Smack
Asked Answered
F

8

9

I am developing chat application by using Openfire XMPP server. I can text chat between two user. But i want to know Typing status when some one is typing message. So i created a class :-

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

    }

}

But i am confuse so that How will it work? I know that i need a packet where i can it in Listener. But i am unable to find that packet.

Please any one suggest, How will it work?

and also what is difference between Smack and asmack?

Thank you!

Forsta answered 26/8, 2013 at 4:18 Comment(1)
Kindly check this question in Stackoverflow : #21155333Obsecrate
U
12

To enable ChatStateListener you need to create a custom MessageListener Class

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

    }

}

Then you create MessageListener object

MessageListener messageListener = new MessageListenerImpl();

And then pass this in the create chat method

Chat newChat = chatmanager.createChat(jabber_id_of_friend, messageListener);

what is difference between Smack and asmack? <-- Check This

Unifoliolate answered 26/8, 2013 at 5:50 Comment(13)
Thank you sunil. looking good and gave me solution. I will check.Forsta
no userID is the jid of the other participant, not the one who logged inUnifoliolate
thank you sunil. if you have a bit time. please check also #18437829Forsta
To handle message events look at this igniterealtime.org/builds/smack/docs/latest/documentation/…Unifoliolate
i checked but did not get stateChanged. plz suggestForsta
please check, It is not working ,i am still unable to get typing status .Forsta
are you sending composing status from the other end?Unifoliolate
sry, i am just using this code. i think, i should use focusonEditText and when user will typing, it will send a composing status. do you have any example ?Forsta
let us continue this discussion in chatUnifoliolate
@SunilMishra getting error on Chat newChat = chatmanager.createChat(jabber_id_of_friend, messageListener);..can u please explain this line? It shows red line with error Cannot make a static reference to the non-static method createChat(String, MessageListener) from the type ChatManagerEvermore
@geet createChat is not a static method, you need an instance of ChatManager to invoke that methodUnifoliolate
It did not work on openfire. type notification need XEP-0085: Chat State Notifications, BUT THE OPENFIRE DOSE NOT HAVE THIS XEP. Any other suggestion except changing openfire?Trefler
Its not working any other solution to get user status..?Barometry
O
4

finally I got the solution. I need to use chat listener along with chat manager and also I need to use in built sendcomposingnotification function. No need to use Messageeventrequestlistener interface or any other custom class for this. I added the following lines,,

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



                    }
                }); 
            }
        });

and also need to send notification like this..

mem.sendComposingNotification(etRecipient.getText().toString(), message.getPacketID());
        System.out.println("Sending notification");

where mem is type of MessageEventManger. Ref: http://www.igniterealtime.org/builds/smack/docs/latest/javadoc/org/jivesoftware/smackx/MessageEventManager.html

Obsecrate answered 21/1, 2014 at 9:56 Comment(4)
hi i tried above..but not working! here is my code! any help will be appreciated....... Message msg1 = new Message(to, Message.Type.chat); msg1.setFrom("[email protected]"); // my id MessageEventManager event=new MessageEventManager(connection); //recipient id event.sendComposingNotification("[email protected]",msg1.getPacketId());Twocycle
@Aneez, you need to process the message received in the processMessage() , because it receives all the incoming packets, not only the typing status. It might be paused, offline/online status packets, or messages.. so try to process it and then handle..Itself
Hi. I tried the same but it did'nt work for me..it neither sendComposingNotification nor receiving it. gives me null at receiving and while received it from ios. Help me to find out this. Thank you.Pavkovic
FYI: merged from #21155333Interlocutress
E
2
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");
        }
});

use this code.hope so will work

Ebonyeboracum answered 16/1, 2015 at 14:25 Comment(8)
Hello, Ahesanali Momin, can you please let me know exact scenario at your end.and what kind of error you are facing in XMPP. for more info message me at skype @ piyush.gupta326. then we can discuss more,your problem and hopefully will reach success point.Ebonyeboracum
I am not getting any error but when i start tyoping code doesn't enter in any state, i mean stateChangeListener not called.Finished
hey man, have you read this doc xmpp.org/extensions/xep-0085.htmlEbonyeboracum
this is completely theory and not interesting as of now, as most of the things pretty clear by using chat client.Finished
I meant, please read the documentation in that link. I hope you will found the solution there. else we can discuss same here.Ebonyeboracum
Should i have to add something while sending message?Finished
Let us continue this discussion in chat.Finished
It was my mistake that i am not sending composing status when user starts typing and send other status when stops typing. But chatstate listener you have mentioned is perfact.Finished
S
1

i am using chat state listener :

Chat chat = chatManager.createChat(jid,
                        new ChatStateChangedListener());

bind the chatstatelistener with each jid like above , then :

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

        }


    }

}
Saloop answered 2/3, 2015 at 10:17 Comment(1)
FYI: merged from #21155333Interlocutress
H
1

Create On Class MMessageListener to listen incoming messages

private class MMessageListener implements 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) {


    }
}

Add Listener to your chat object

Chat Mychat = ChatManager.getInstanceFor(connection).createChat( "user2@localhost"), mMessageListener);

Send status to receiving user on edittext text change

ChatStateManager.getInstance(connection).setCurrentState(ChatState.composing, Mychat);

This works fine for me.

Hexosan answered 7/11, 2015 at 6:23 Comment(3)
Hi Dharmesh, i did the same but i am getting null always in composing state message in processMessage. My EditText text change method is : newChat = chatmanager.createChat(send_to, messageListener); Message msg = new Message(send_to, Message.Type.chat); msg.setFrom(USERNAME_LOGIN+"@"+HOST_NAME); // my id newChat.sendMessage(msg); ChatStateManager.getInstance(connection).setCurrentState(ChatState.composing, newChat); And this also not send status to others.Pavkovic
FYI: merged from #21155333Interlocutress
How to check if user has paused or is no longer typing in the editext?Gregoriogregorius
J
0

Your or another xmpp client which you use, should sending chat state for You can catch the state.

Like This;

try {
      ChatStateManager.getInstance(GlobalVariables.xmppManager.connection).setCurrentState(ChatState.composing, chat);
    } catch (XMPPException e) {
        e.printStackTrace();
    }

or

try {
        ChatStateManager.getInstance(GlobalVariables.xmppManager.connection).setCurrentState(ChatState.gone, chat);
    } catch (XMPPException e) {
        e.printStackTrace();
    }
Joubert answered 24/11, 2014 at 12:37 Comment(4)
Maybe your Server application doesnt support it.Joubert
you mean to say our server is not configure for that ? but its working fine with ios to ios. i am writting this line on textChangeListner of EditText. and chat object is chatmanager = connection.getChatManager(); Chat chat = chatmanager.createChat("user@", listner); Even when i receive compose status from ios processMessage gives me null. Please help me to find solution for both send and receive. P.S. i am using asmack libraryPavkovic
FYI: merged from #22225894Interlocutress
This needs to be done on editext text text change listener..right?Gregoriogregorius
U
0

However you can get it from ProcessPacket also. there you will get a Message object, after you can extract xml portion from there and handle them its contain specific chatstate or not.

    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
    }

now handle as per your requirement.

Uyekawa answered 4/8, 2016 at 11:47 Comment(0)
P
0

Just add ChatStateManager after ChatManager intalization:

chatManager =  ChatManager.getInstanceFor(getXmpptcpConnection());
ChatStateManager.getInstance(getXmpptcpConnection());

Then you need to add ChatStateListener during createChat(to,chatMesageListener):

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());
    }
};
Penelopa answered 7/10, 2016 at 11:37 Comment(2)
FYI: merged from #22225894Interlocutress
Next time, maybe just answer one question and flag the rest to let us know that they're duplicates; posting the same answer 7 times is pretty excessive.Interlocutress

© 2022 - 2024 — McMap. All rights reserved.