2
votes

I am creating an instant messaging app in android using smack library and openfire as a server but i cannot implement the feature of the person with whom the current user is talking to. i.e. like when user read the message or when he starts typing. Is there any way of achieving this using smack or other ?

1

1 Answers

2
votes

For knowing which user is current you must implement your own in your logic. You must use Roster (contact list in xmpp servers) to get contacts of current user and save them in database or somewhere. Then create an activity to show contacts in a list. Each contact has a unique jid that can be distinguished from others with it. So with click on each contact, send it's object(include jid) to chat-activity. In chat-activity you must get previous messages from database or MAM(archived messages in server) and you can send a message to current contact(set contact jid as To).

To achieving delivery of message you must use this link. you can set request of it with this code:

Message message = …  //make your stanza
DeliveryReceiptRequest.addTo(message); //add delivery request to message
connection.sendStanza(message);   //send message

then you can be notified of delivery with this code:

private void setDelRecListener() {
    DeliveryReceiptManager d = DeliveryReceiptManager.getInstanceFor(connection);
    d.addReceiptReceivedListener(new ReceiptReceivedListener() {
        @Override
        public void onReceiptReceived(Jid fromJid, Jid toJid, String receiptId, Stanza receipt) {
            Msg msg = F.getMsgBySid(receiptId);
            if (msg == null)
                return;
            Boolean isUpdated = F.setMsgDelivered(msg);
            Log.i("m/serv/UpdateDelivery", "for: " + receiptId + (isUpdated ? " Founded&Updated" : " NotFounded"));
            if (isUpdated) {
                BCTool.notifyPMDelivered(msg.id, msg.conv.frnd.getBareJid());
            }
        }
    });
}

Keep in mind that every stanza has a sid(stanza id) and you must save each corresponding sid to message model in database when send is successful. This way you can detect which message delivery you got. - For sending chat states like composing you can use this method:

public void sendChatState(String _jid, ChatState chatState) {
    try {
        Message msg = new Message();
        msg.addExtension(new ChatStateExtension(chatState));
        msg.setTo(JidCreate.bareFrom(_jid));
        msg.setType(Message.Type.chat);
        connection.sendStanza(msg);
        Log.e("m/service", "ChatStateSent");
    } catch (SmackException.NotConnectedException | InterruptedException | XmppStringprepException e) {
        Log.e("m/service", "ChatState Not Sent: " + e.getMessage());
        e.printStackTrace();
    }
}

You must set a timer to prevent send composing in next 5Sec and reset timer when a character typed. Consider reading this: ChatStateNotifications