I am able to add Entry to the Xmpp account by using this code. i can't get subscription "both", instead of this i am getting none.
roster.createEntry("abc#xyz.com", "abc", null);
How to add entry with the presence type=both, when i am subscribing entry to this account. I want to know whether xmpp publish-subscribe functionality ?
How to get Inbound presence notifications ?
How to send Outbound presence notifications ?
EDIT :
public void Addcontact() {
Roster.setDefaultSubscriptionMode(Roster.SubscriptionMode.manual);
Roster roster = m_connection.getRoster();
if(!roster.contains("pa#ace.com")) { try {
roster.createEntry("pa#ace.com", "pa", null);
} catch (XMPPException e) {
e.printStackTrace();
}
}else {
Log.i("Acc = ", "contains");
}
}
I am adding entry like this still i am getting Presence Type = none..
Here is how I add another friend in my application.
protected void doAddContactToListAsync(String address, String name,
ContactList list) throws ImException {
debug(TAG, "add contact to " + list.getName());
Presence response = new Presence.Type.subscribed);
response.setTo(address);
sendPacket(response);
Roster roster = mConnection.getRoster();
String[] groups = new String[] { list.getName() };
if (name == null) {
name = parseAddressName(address);
}
try {
roster.createEntry(address, name, groups);
// If contact exists locally, don't create another copy
Contact contact = makeContact(name, address);
if (!containsContact(contact))
notifyContactListUpdated(list,
ContactListListener.LIST_CONTACT_ADDED, contact);
else
debug(TAG, "skip adding existing contact locally " + name);
} catch (XMPPException e) {
throw new RuntimeException(e);
}
}
Just use the essential part
Presence response = new Presence.Type.subscribed);
response.setTo(address);
sendPacket(response);
Roster roster = mConnection.getRoster();
roster.createEntry(address, name, groups);
In order to listen to incoming request, register addPacketListener to your connection
mConnection.addPacketListener(new PacketListener() {
#Override
public void processPacket(Packet packet) {
Presence presence = (Presence) packet;
if (presence.getType() == Type.subscribe) {
debug(TAG, "sub request from 1" + address);
//Implement accept or reject depend on user action.
mContactListManager.getSubscriptionRequestListener()
.onSubScriptionRequest(contact);
//or you can test with send back Presence.subscribe first and send Presence.subscribed back to requester.
} else {// Handle other Presence type.
int type = parsePresence(presence);
debug(TAG, "sub request from " + type);
contact.setPresence(new Presence(type,
presence.getStatus(), null, null,
Presence.CLIENT_TYPE_DEFAULT));
}
}
}, new PacketTypeFilter(Presence.class));
mConnection.connect();
The right order:
User1 send Subscribe to user2.
User2 send Subscribe and Subsribed back to user1.
User1 send Subsribed to user2.
Another SO question you can check
Related
Hey i am developing Chat Application using XMPP Smack Library. Recently i am working on Group Chat While sending Group message some message will be drop so receiver wouldn't receives message from the sender side. it will gives me 400 bad request.
it is working sometimes. and sometimes not work
here i found this kind of message in 400 bad request.
<?xml version="1.0" encoding="UTF-8"?>
<message to="156#abc.com/Android" id="nXlV6-1144" type="error" from="24#confrence.abc.com/156#abc.com.com">
<received xmlns="urn:xmpp:receipts" id="nXlV6-1142" />
<error code="400" type="modify">
<bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
</error>
</message>
if successfully send message it will give this kind of message.
<?xml version="1.0" encoding="UTF-8"?>
<message to="156#abc.com/Android" id="nXlV6-1411" type="groupchat" from="24#conference.abc.com/156#abc.com">
<body>eyu4u4</body>
<chatDetail xmlns="jabber:x:oob">
<UID>156</UID>
<time>04:20 PM</time>
<user_icon>24_group_icon.jpg</user_icon>
<SentTime>1474368652960</SentTime>
<USERName>vasudev89</USERName>
<user_name>cryan</user_name>
<message>eyu4u4</message>
<type>group</type>
<phone_number>24</phone_number>
</chatDetail>
<request xmlns="urn:xmpp:receipts" />
</message>
how i can send message persistently? Any idea?
Thank You in Advance.
here is my code sending muc message:
public boolean sendGroupMessage(Message message, String strGroupID) {
DeliveryReceiptRequest.addTo(message);
try {
Log.i(TAG, "sendGroupMessage");
//Log.i("JOIN MUC","To join group chat: " + groupChat.getClassId());
// Get the MultiUserChatManager
MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(AbstractXMPPConnection);
// Create a MultiUserChat using an XMPPConnection for a room
MultiUserChat muc = manager.getMultiUserChat(strGroupID + AppWSConstants.XMPP_JID_GROUP_CHAT_SUFFIX);
muc.sendMessage(message);
return true;
} catch (NotConnectedException e) {
e.printStackTrace();
}
return false;
}
#LearnPainLess, follow these steps to solve group chat issue
-when creating groups, save the jid of group in the database, like "somegroup#conference.{domain}.com"
-create background task for creating xmpp connection (this way it will always be connected)
-after logging in to xmpp, get the group names from the database and connect to them
also, in openfire, Group Chat > Group Chat Settings > Edit Icon > Default Room Settings > Check "Make Room Persistant"
also, in other settings > Never kick idle users
I have an XmppBase class where i put all my xmpp code
All listeners in seperate folder
Connection is stored in static variable and i retrive it using
Utils.getConnection()
// this function m calling from background service and everywhere if not connectect to xmpp
public static XMPPConnection CreateXmppConnection() {
if (Utils.getConnection() == null) {
try {
Boolean isConnected = new XmppAsync(mUsername, mPassword,context).execute().get();
if (isConnected && Utils.getConnection() != null) {
RegisterConnListeners(Utils.getConnection());
updateMyProfileImg();
// connect to all groups
DBAdapter adapter = new DBAdapter(context);
adapter.openForRead();
List<UserDetail> groups = new ArrayList<>();
adapter.addAllGroups(groups);
adapter.addPastChatGroups(groups);
adapter.close();
for(UserDetail g : groups)
{
CreateXmppMUCSession(g.getGroupTemp());
}
return Utils.getConnection();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return null;
} else
return Utils.getConnection();
}
// get muc chat manager
public static MultiUserChatManager getMucManager() {
if(mucManager != null)
return mucManager;
if (Utils.getConnection() != null) {
return MultiUserChatManager.getInstanceFor(Utils.getConnection());
} else {
if (CreateXmppConnection() != null)
return MultiUserChatManager.getInstanceFor(Utils.getConnection());
else {
Log.v("error", "Some Error Occured");
Toast.makeText(context, "Cant Connect to Xmpp", Toast.LENGTH_SHORT).show();
return null;
}
}
}
// create muc session and m passing group name - call when you open chat page
public static void CreateXmppMUCSession(String gName)
{
RegisterGroupChatListeners(gName);
}
// connect to muc if not already connected
public static void RegisterGroupChatListeners(String groupName)
{
try {
mStateManager = getChatStateManager();
multiUserChat = getMUC(groupName);
// if(multiUserChat != null) {
multiUserChat.addMessageListener(new MyMUCMessageListener());
try {
if (!multiUserChat.isJoined()) {
DiscussionHistory discussionHistory = new DiscussionHistory();
discussionHistory.setMaxStanzas(0);
multiUserChat.join(new MyPrefrence(context).getUsername().split("#")[0], "123",
discussionHistory, SmackConfiguration.getDefaultPacketReplyTimeout());
}
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
// }
}
catch (Exception ex)
{
//
}
}
// get muc
public static MultiUserChat getMUC(String groupName)
{
// Log.v("nick",multiUserChat.getNickname() + " , g = " + groupName);
// if(multiUserChat != null && multiUserChat.getRoom().contains(groupName))
// {
// return multiUserChat;
// }
if (Utils.getConnection() != null) {
MultiUserChatManager chatManager = getMucManager();
if (chatManager != null) {
return chatManager.getMultiUserChat(groupName);
} else {
Toast.makeText(context, "Cannot create Chat", Toast.LENGTH_SHORT).show();
return null;
}
} else {
if (CreateXmppConnection() != null) {
MultiUserChatManager chatManager = getMucManager();
if (chatManager != null) {
return chatManager.getMultiUserChat(groupName);
} else {
Toast.makeText(context, "Cannot create Chat", Toast.LENGTH_SHORT).show();
return null;
}
}
else {
Toast.makeText(context, "Cannot create Chat", Toast.LENGTH_SHORT).show();
return null;
}
}
}
and whenever i want to send message i just call this
public static Boolean sendMUCChatMsg(Message msg)
{
if(multiUserChat != null)
try {
multiUserChat.sendMessage(msg);
return true;
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
return false;
}
Sorry if it looks clumpsy, if I missed any function there let me know, but this is working code which i am using
try this,
I modified your last function
static MultiUserChat multiUserChat;
// call this function when you open the chat window
private void CreateGroupConnection(String strGroupID ) {
// Get the MultiUserChatManager
MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(AbstractXMPPConnection);
// Create a MultiUserChat using an XMPPConnection for a room
MultiUserChat multiUserChat = manager.getMultiUserChat(strGroupID + AppWSConstants.XMPP_JID_GROUP_CHAT_SUFFIX);
return multiUserChat;
}
// whenever sending message from chat call this
publilc static void sendMucMessage(Message message){
if(multiUserChat != null)
multiUserChat.sendMessage(message);
}
I am working on "seen and delivered" in MUC and facing with this issue when replying back with the same packet id, still testing but I think in your case you should move your xmpp connection to background service and after connecting to xmpp on device launch up, connect to all the muc in your database. This way you will always be connected to groups.
cause : according to me, when the other user is not connected to the muc and you send a message or when you reply to the group with the same packet id.
Note: I am using multiuserchat.sendmessage to send group message and chat.sendmessage to send message to single user
SMACK 4.1
** update **
I fixed it by creating new packet instead of modifying the one i am receiving
here is the packet
Message msgg = new Message();
msgg.setBody(message.getPacketID());
msgg.setSubject(MessageModel.CHAT_STATUS_SEEN + "");
XmppBase.sendMUCChatMsg(msgg);
in your case, try with simple packet first. if all works well, then add extension one by one and see where you get the error, Thanks
I create an App that a user can send messages(notifications) in other users. Fot these perpose i use parse SDK. So i send the message from device into the parse cloud with below code.
final ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereEqualTo("email", "user#email.com");
query.getFirstInBackground(new GetCallback<ParseUser>() {
public void done(ParseUser object, ParseException e) {
if (e == null) {
Toast.makeText(getActivity(), "User found", Toast.LENGTH_SHORT).show();
String search_username = object.getString("username");
String id = object.getObjectId();
Log.d("ObjectID:",id);
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("recipientId", id);
params.put("message", username);
ParseCloud.callFunctionInBackground("sendPushToUser", params, new FunctionCallback<String>() {
public void done(String success, ParseException e) {
if (e == null) {
// Push sent successfully
Toast.makeText(getActivity(), "Request send", Toast.LENGTH_SHORT).show();
}
}
});
Then i have the next cloud function for recieve and push the message to the specific user.
Parse.Cloud.define("sendPushToUser", function(request,response){
var senderUser = request.user;
var recipientUserId = request.params.recipientId;
var message = request.params.message;
var title ="Friend Request";
if(message.length > 140){
message = message.substring(0, 137) + "...";
}
var recipientUser = new Parse.User();
recipientUser.id = recipientUserId;
var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.equalTo("user", recipientUser);
Parse.Push.send({
where: pushQuery,
data: {
"alert":{"data":{"message":"message",
"title":"title"}}
}
}).then(function(){
response.success("true")
}, function(error) {
response.error("Push failed to send with error: "+error.message);
});
});
But the message never been received. If i sent a push notification from parse dashboard everything works fine. Anyone knows how to solve it? The device expect a JSON to received so may my cloud function didnt send data in json format? Thanks in advance
I had problems while sending notifications because of 2 things
enabling client push "not in your case"
didn't save the user in the installation "try the following"
After the user logs into your app add his id to the installation by
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
installation.addUnique("userId", currentUser.getObjectId());
installation.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
// check the returned exception
if (e == null) {
// everything worked fine
} else {
// error occurred
}
}
});
hope it helps :)
Update
In your code you're sending the recipient userId although you saved the username also in your cloud function you have the same problem, the username is saved but you query the installation based on the id. I've updated the installation above also change the "user" in your cloud function to the "userId"
pushQuery.equalTo("userId", recipientUser);
Is any way in xmpp that i get offline message of MultiUserChat, when my user login and join room.
I want implement group chat like WhatsApp, Is any other way to implement this please suggest
Thanks in advance
At least in ejjaberd when you enter the chat group, you have to enter your last timestamp, given that timestamp you will receive the messages from that moment.
Save the timestamp from your last message, and when you enter to your room, like the following:
MultiUserChat muc = new MultiUserChat(mConnection, room_name);
Log.d(TAG, "JOINING => " + room_name);
DiscussionHistory history = new DiscussionHistory();
if (mLastMessageDate == null)
history.setMaxStanzas(300);
else
history.setSince(mLastMessageDate); //timestamp from your last message
muc.join(mNickName, null, history,
SmackConfiguration.getDefaultPacketReplyTimeout());
Hope it helps
First declare a MultiUserChat this way
private static MultiUserChat muc = null;
then in your oncreate method instantiate it this way
muc = new MultiUserChat(CONNECTION, room);
try {
muc.join(USERJID);
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
and call this method in the beginning of your app
void setMessageListner() {
muc.addMessageListener(new PacketListener() {
#Override
public void processPacket(Packet packet) throws SmackException.NotConnectedException {
Message msg = (Message)packet;
msg.setSubject(msg,getBody);
Logger.i("Received message : "+msg.getBody()+" From "+msg.getSubject());
});
}
this way whenever the user get into a GroupChat he will get the last Messages of the group
I am using quickblox api for video chat and i want to get online available user .I know that it can be done through roster but i don't know how to get roster and how to add entries in roster .i want this through quickblox connection and dont know how to get xmpp connection.
XMPPConnection.addConnectionCreationListener(new ConnectionCreationListener() {
#Override
public void connectionCreated(Connection arg0) {
Log.i(TAG, "receive xmpp connection : " + arg0);
connection = arg0;
roster = arg0.getRoster();
Collection<RosterEntry> entries = roster.getEntries();
Presence presence;
Log.e(TAG, "user count" + entries.size());
for (RosterEntry entry : entries) {
presence = roster.getPresence(entry.getUser());
Log.i(TAG, "" + entry.getUser());
Log.i(TAG, "" + presence.getType().name());
Log.i(TAG, "" + presence.getStatus());
}
}
});
So at the start of your program register that XMPPConnection listener, usually it take few seconds to receive connection object.
But it will work only if you will use creatEntry only in that case rooster will see those created users.
To creat entry using Roster use next code:
try {
rooster.createEntry("name", "user_id", null);
} catch (XMPPException e) {
e.printStackTrace();
}
I didn't use any group, and with success see user on second device.
I am new to the use of smack library and making one chatting application. I have made upto much extent and at this step i want to ask two questions.
when i add a friend the friend got added in my list but there is not any notification sent to the FRIEND whom i have added, How to achieve the same. I have added the code below.
The second thing i want to ask is that how can I check whether the user which I am going to add is a part or member of the app or not ( mean it is on the server or not). So that the user who is not registered to the app should not be added in the friends list.
here is the code
public static boolean addFriend(String jid) {
String nickname = null;
nickname = StringUtils.parseBareAddress(jid);
RosterEntry entry4 = roster.getEntry("samsad");
if (!roster.contains(jid)) {
try {
Presence subscribe = new Presence(Presence.Type.subscribe);
subscribe.setTo(jid);
connection.sendPacket(subscribe);
roster.createEntry(jid, nickname, null);
// Send a roster entry (any) to user2
RosterExchangeManager REM = new RosterExchangeManager(connection);
REM.send(entry4, jid);
return true;
} catch (XMPPException e) {
System.err.println("Error in adding friend");
return false;
}
} else {
return false;
}
}
Roster Exchange manager running in the service in background
/**Remotr Exchange Manager*/
RosterExchangeManager rem = new RosterExchangeManager(connection);
// Create a RosterExchangeListener that will iterate over the received roster entries
RosterExchangeListener rosterExchangeListener = new RosterExchangeListener() {
public void entriesReceived(String from, Iterator remoteRosterEntries) {
notification("Receive==4");
while (remoteRosterEntries.hasNext()) {
try {
// Get the received entry
RemoteRosterEntry remoteRosterEntry = (RemoteRosterEntry) remoteRosterEntries.next();
// Display the remote entry on the console
System.out.println(remoteRosterEntry);
// Add the entry to the user2's roster
roster.createEntry(
remoteRosterEntry.getUser(),
remoteRosterEntry.getName(),
remoteRosterEntry.getGroupArrayNames());
notification("Receive==1");
}
catch (XMPPException e) {
e.printStackTrace();
}
}
}
};
rem.addRosterListener(rosterExchangeListener);
}
else{
showToast("Connection lost-",0);
}
}
1, The problem is you must register a PacketListener for Presence.Type.subscribe before you connect to server. All the process of add and accept friend i answered in here
2, You can use UserSearch class to search for a specific user and if user is not found on server then you can assume that user is not registered on server.