Who are you returning the Message to? Keep in mind that your registered your listener with the Smack framework, and it is not expecting a Message in return. This is largely why you cannot change the method to return a Message.
If you are referring to returning a message to the sender of the received msg, then you are asking the same question I am in a different thread. I haven’'t found any methods to get from either a Packet or a Message to the Chat in order to createMessage() and sendMessage() back to the sender.
My quess at this time is that I might have to setup a ConnectionListener to be called when the Chat is established and track it myself perhaps in a Map keyed on the “From” value. This does seem like a method that is missing in the Smack API. Obviously if I am receiving a message, that message originated from a Chat which I might want to respond to.
AFAIK smack currently does not have such a mapping as from a Message object to a Chat Object. I seem to remember reading a thread a while ago that it maybe something that will be added in the future.
As for the moment, most implementations I’'ve seen do as you suggest. Storing chats in a construct such as a Map, and using the from value as a key.
FYI: we are working on some major changes to how chats are handled for the next version of Smack, this goes without saying that this contains major API changes. Here is what we are thinking of:
Central chat control through a ChatManager class through this you have the ability to add a MessageListener when fired the MessageListener looks like this:
void messageRecieved(Chat chat, Message message);
Finer grained control will be retained by keeping the ability to add a MessageListener to a particular chat.
I did get this working, and it is a lot simpler than I thought. No Map of Chats or anything like that. The trick is not to think about the Chat object as a connection as I was. It is a sequence of messages. So my packet listener gets a Message (filtered, so I know it is a message), and I do the following:
Message msg = (Message)packet;
Chat chat = new Chat(connection, msg.getFrom(), msg.getThread());
Message reply = chat.createMessage();
…
chat.sendMessage(reply);
That did it. As far as the new ChatManager, I’‘m not sure. I don’‘t want to lose the Chat.nextMessage() capability as I use it for synchronous request/reply exchanges. Sounds like it would work for asynchronous exchanges or situations where I want to handle messages through one listener, though. I’‘m OK with the current PacketListeners for that at the moment, as I don’'t break out separate Listeners for each chat. It might be handy though.