Duplicate message received in XMPP Multi User Conference Room - xmpp

When device1 is sending the message to the conference room "del#conference.jabber.org"
the message is dispalyed in the chat list as well as a duplicated message is also displayed that is being send by the conference room "del#conference.jabber.org". I'm stuck, why i'm getting duplicate message.
public void setConnection(XMPPConnection connection) {
this.connection = connection;
if (connection != null) {
PacketFilter filter = new MessageTypeFilter(Message.Type.groupchat);
connection.addPacketListener(new PacketListener() {
#Override
public void processPacket(Packet packet) {
Message message = (Message) packet;
if (message.getBody() != null) {
String fromName = StringUtils.parseBareAddress(message.getFrom());
String[] parts = fromName.split("#");
String from = parts[0].trim();
messages.add(from + ":");
messages.add(message.getBody());
// Add the incoming message to the list view
mHandler.post(new Runnable() {
public void run() {
setListAdapter();
}
});
}
}
}, filter);
}
}
The send message is on button click, which is as follows
Button send = (Button) this.findViewById(R.id.sendBtn);
send.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Message mg = muc.createMessage();
String text = textMessage.getText().toString();
mg.setBody(text);
Log.i("XMPPChatDemoActivity ", "Sending text ");
if (connection != null) {
connection.sendPacket(mg);
messages.add("Me :");
messages.add(text);
setListAdapter();
}
textMessage.setText("");
}
});
and this is what i have written to connect the conference room
muc = new MultiUserChat(connection, "del#conference.jabber.org");
muc.join("alias name","password");
output what i'm getting when sending message
me: hello
del: hello
what i want i no duplicate message when i send the message i.e
me: hello

When you're in a MUC room you receive copies of all the messages, including your own.
http://xmpp.org/extensions/xep-0045.html#message - "and reflect the message out to the full JID of each occupant."
So for MUCs (not for direct messages) you will get a duplicate if you log both on send and on receive (assuming you have sufficient access to post, etc.). Your options are, largely, either to not log it on send (which is the option most clients go for) or to attempt to do smart message matching to detect when you receive your own message and elide it. The former option ensures that everyone sees a consistent view of message ordering, which some people find very useful.

Maybe your chat server sent your message to you also?
So you add one message manually in onClickListener and then the same message received from server.
I think, it will be right not to add messages from onClickListener - add only those that server sends.

Related

How to know who received a message in a MUC room

For my thesis, I am using Smack to log a XMPP network that uses the MUC module.
Another software is currently sending IoT sensor data into different MUC rooms.
I'd like to know for every message sent into a MUC room, which users were in that room at the time of the message. Is this possible? I could use a messageListener to every muc room, however the listener only receives a message as an argument. Therefore I could not know who is logged into the room inside the listener method.
you can get all muc message in StanzaListener in xmpp. Please follow few steps to done this
Step 1. Declare as a global variables
ChatManagerListener chatListener;
Chat chat;
StanzaListener packetListener;
Step 2. Use this code in oncreate or in fragment
Note: Make sure you have connected with chat server.
packetListener = new StanzaListener() {
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException, InterruptedException {
if (packet instanceof Message) {
final Message message = (Message) packet;
}
}
};
XMPP.getInstance().getConnection(acitiviy)).addAsyncStanzaListener(stanzaListener, null);
ServiceDiscoveryManager sdm = ServiceDiscoveryManager
.getInstanceFor(XMPP.getInstance().getConnection(acitiviy)));
sdm.addFeature("jabber.org/protocol/si");
sdm.addFeature("http://jabber.org/protocol/si");
sdm.addFeature("http://jabber.org/protocol/disco#info");
sdm.addFeature("jabber:iq:privacy");
Step 3. Methods for one to one chat purposer
void sendMessage(String message) {
if (chat != null) {
try {
chat.sendMessage(message);
Message msg = new Message();
msg.setTo(JidCreate.bareFrom(jid));
msg.setFrom(XMPP.getInstance().getConnection(acitiviy)
.getUser());
ChatStateExtension ext = new ChatStateExtension(
ChatState.paused);
msg.addExtension(ext);
lastComposing = System.currentTimeMillis();
chat.sendMessage(msg);
} catch (SmackException.NotConnectedException e) {
} catch (Exception e) {
}
}
}
Step 4. On destroy
XMPP.getInstance().getConnection(acitiviy)).removeAsyncStanzaListener(stanzaListener);
Hope this will help you and if you want more information take a look from here. Thankyou
Nothing prervents you from calling Multi UserCaht.getParticipants() from within the listener. But be warned: If your goal is to determine the other receivers of receivers, then this approach is fragile. I also suggest to think about using PubSub instead of MUC for your IoT use case.

smack receive message in muc using 4.1.0 rc1

Can anybody tell me how to receive message in muc using Smack 4.1.0 rc1?
I am able to send message using below code.
Message message = new Message();
message.setType(Message.Type.groupchat);
message.setBody(strMessage);
message.setTo(roomJid);
multiUserChat.sendMessage(message);
I am using below code but not able to get the message.
multiUserChat = multiUserChatManager.getMultiUserChat(roomJid);
multiUserChat.addMessageListener(new MessageListener() {
#Override
public void processMessage(Message message) {
Log.i(Constant.TAG, "processMessage");
}
});
My debugging is on and i can see that app is receiving message(D/SMACK( 6098): RECV (1):
) but listener is not getting called
Use MultiUserChat.addMessageListener(MessageListener).
send presence / join to muc before adding message listener to the muc.
then you will get muc message into the listener.
without sending presence or join to the muc, you can not get the message into the listener but you can see in the logcat.
I'm using stanza listener and able to receive MUC messages.
final StanzaListener stanzaListener = new StanzaListener() {
#Override
public void processStanza(Stanza packet) throws SmackException.NotConnectedException, InterruptedException { .. }
xmppConnection.addAsyncStanzaListener(stanzaListener, StanzaTypeFilter.MESSAGE);

Get pending messages from a Chat

I am developing a chat using quickblox but I am having some problems when I open a new chat. Suddenly I received all the messages that others users sends to me when I was desconnected. The problem is that when I start a chat with user A, I receive the chats from users B, C, D.. in user A chat room.
I have find the way to only show the A users. But the problem is that the server has already sent to me the "disconnected" messages, so when I start a chat to B I do not receive any text because the message that the user B sent to me has been delivered (and ommitted) while I was chating with user A.
How can I do to receive the pending messages (kind of history) or to just retreive the message of the chat I am logged in?
A piece of my code:
// Create Connection.
Connection.DEBUG_ENABLED = true;
config = new ConnectionConfiguration(CHAT_SERVER);
connection = new XMPPConnection(config);
try {
connection.connect();
connection.login(chatLogin, password);
// Create Chat Manager.
chatManager = connection.getChatManager();
// Create Chat.
chat = chatManager.createChat(friendLogin, null);
// // Set listener for outcoming messages.
// chatManager.addChatListener(chatManagerListener);
// Accept only messages from
String from_messages = Integer.toString(receiver_chat_id);
PacketFilter filter = new AndFilter(new PacketTypeFilter(Message.class),
new FromContainsFilter(from_messages+"-3758#chat.quickblox.com"));
// Collect these messages
PacketCollector collector = connection.createPacketCollector(filter);
Packet packet = collector.pollResult();
PacketListener myListener = new PacketListener() {
public void processPacket(Packet packet) {
if (packet instanceof Message) {
Message msg = (Message) packet;
if(msg!=null){
// Process message
System.out.println("Rebem missatge: " +msg.getBody());
}
}
}
};
// Register the listener.
connection.addPacketListener(myListener, filter);
// Set listener for detect Receiver Status
if (connection.isConnected()){
roster = connection.getRoster();
roster.addRosterListener(new RosterListener() {
public void entriesDeleted(Collection<String> addresses) {}
public void entriesUpdated(Collection<String> addresses) {}
public void presenceChanged(Presence presence) {}
public void entriesAdded(Collection<String> arg0) {}
});
}
Make a arraylist and store the receiving offline messages into that array-list. you could add a code in your processPacket(Packet packet) function to add incoming messages to the array-list. or you could use Multimaps(Google Guava) to store all the incoming messages with the key. and when you open the activity that displays the messages from the certain person you could match the name of that person with the key(stored in multimap) and displays the message of that certain person. And the better option is to store all the incomming and outgoing message chat with the certain person so that you could show all the previous chat then you open up the activity.

android GCM Receive Messages from Multiple devices

i am building a chat application with the help of GoogleCloudMessaging(GCM).i am able to send and receive messages. my problem is when i receive messages from multiple devices at the same time, all those messages are appended to the same list-view in my broadcast receiver class. how can i separate the message based on the senders and append the current chat message to the listview. and make separate notifications for other messages based on the senders and when i click on the notification it should open the same list view with messages according to sender.
can any one give me an efficient way of doing this.if you have any sample code to handle this situation please post the code.
My current code:
public class Serious extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action=intent.getAction();
if (action.equals("com.google.android.c2dm.intent.REGISTRATION"))
{
String registrationID=intent.getStringExtra("registration_id");
// Log.i("uo",registrationID);
String error=intent.getStringExtra("error");
String unregisterd=intent.getStringExtra("unregistered");
}
else if(action.equals("com.google.android.c2dm.intent.RECEIVE"))
{
String data1=intent.getStringExtra("data1");
String data2=intent.getStringExtra("data2");
addNewMessage(new Message(data2, false));
/* PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class), 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("My Notification")
.setDefaults(Notification.DEFAULT_SOUND)
.setAutoCancel(true)
.setContentText(data1+data2);
mBuilder.setContentIntent(contentIntent);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());*/
}
}
void addNewMessage(Message m)
{
MainActivity.messages.add(m);
MainActivity.adapter.notifyDataSetChanged();
//MainActivity.getListView().setSelection(MainActivity.messages.size()-1);
}
}
You should pass in your gcm message a parameter that contains the sender id. Then, when you handle the arrived message, use that sender id to decide where to add that message. In order to show multiple notifications, pass different int values to notify. Currently you always pass 1, so a new notification overrides the old one.

JavaMail Get Message for Undelivered Emails (to Gmail or Ymail)

I'm trying to build an app to send bulk report emails to many addresses with various hosts. I'm using Javamail and well, I'm still learning it though.
I found an example and try sending emails with my company server as host (let's say xyz company).
here is the sample code
package mailexample;
import javax.mail.*;
import javax.mail.internet.*;
public class MailExample {
public static void send(String smtpHost, int smtpPort,
String from, String to,
String subject, String content) {
try {
java.util.Properties props = new java.util.Properties();
props.put("mail.smtp.host", smtpHost);
props.put("mail.smtp.port", ""+smtpPort);
Session session = Session.getDefaultInstance(props, null);
//Store store = session.getStore();
//Folder folder = store.getFolder("INBOX");
//System.out.println(folder.getMessage(1));
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(from));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
msg.setSubject(subject);
msg.setText(content);
Transport.send(msg);
}
catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
try {
send("mail.xyz.ac", 25, "asdf#xyz.ac", "qwer#xyz.ac",
"title", "content");
}
catch(Exception e) {
e.printStackTrace();
}
}
}
It works fine and I get an error stacktrace when the address is invalid.
But that is only happen if I send an email to the same server/host which is mail.xyz.ac.
If I send an email to some random gmail or ymail addresses (that likely don't exist), my app return success message but nothing happened after that, only a message (like mailer-daemon in gmail) in sender inbox that said it is not delivered.
The problem is, I need to store that message in my database for further notice.
Is it possible to get that message from my app?
The JavaMail FAQ is your friend while learning JavaMail. This entry and this entry address your question. Also, be sure to read the entry about common mistakes.