I am working on a chatting application in which i can send messages , images , videos etc
i have done this in one to one chat also fulfill it in group chat .
But the issue is :-
I have to always join the each group everytime i login otherwise i am not been able to recieve message from different groups .
here is the way i join group each time .
MultiUserChat muc= new MultiUserChat(mConnection,"hsjsmqb#conference.11.111.111.111");
String userNAme ="222222222";
muc.join(userNAme);
if i do not join group everytime i do not recieve messages .
if i join group i started recieving messages .
My Question is is this the only solution or all group chatting works this way.
or am i doing some thing wrong
i googled but did not find any solution .
if it is duplicate question or any answer related to my question please share the link
thanks
This is the code :-
public boolean createChatRoom() {
String name = edtGroupName.getText().toString();
if (!(connection.isConnected() && name.length() != 0)) {
return false;
}
try {
// Create a MultiUserChat
String userName = Utils.covertIntoSubString(connection.getUser(), Constant.AT);
roomName = (name + md5String(getDateTime()) + userName + Constant.CONFERENCE + connection.getServiceName()).replaceAll(" ", "");
MultiUserChat muc = new MultiUserChat(connection, roomName);
// Create a chat room
muc.create(roomName);
// set Room Name as room subject
muc.changeSubject(name);// RoomName room name
// To obtain the chat room configuration form
Form form = muc.getConfigurationForm();
// Create a new form to submit the original form according to the.
Form submitForm = form.createAnswerForm();
// To submit the form to add a default reply
for (Iterator<FormField> fields = form.getFields(); fields
.hasNext(); ) {
FormField field = (FormField) fields.next();
if (!FormField.TYPE_HIDDEN.equals(field.getType())
&& field.getVariable() != null) {
// Set default values for an answer
submitForm.setDefaultAnswer(field.getVariable());
}
}
// Set the chat room of the new owner
List<String> owners = new ArrayList<String>();
owners.add(connection.getUser());// The user JID
// submitForm.setAnswer("muc#roomconfig_roomowners", owners);
// Set the chat room is a long chat room, soon to be preserved
submitForm.setAnswer("muc#roomconfig_persistentroom", true);
// chat room is public
submitForm.setAnswer("muc#roomconfig_publicroom", true);
// Allows the user to modify the nickname
submitForm.setAnswer("x-muc#roomconfig_canchangenick", true);
// Allows the possessor to invite others
// submitForm.setAnswer("muc#roomconfig_allowinvites", true);
// submitForm.setAnswer("muc#roomconfig_enablelogging", true);
// Only allow registered nickname log
// submitForm.setAnswer("x-muc#roomconfig_reservednick", true);
// Allows the user to register the room
// submitForm.setAnswer("x-muc#roomconfig_registration", true);
muc.sendConfigurationForm(submitForm);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
public void inviteFriends(String userJid) {
try {
String groupName = edtGroupName.getText().toString();
Message msg = new Message();
msg.setBody(groupName);
MultiUserChat muc = new MultiUserChat(connection, roomName);
if (muc != null) {
muc.grantMembership(userJid);
muc.invite(msg, userJid, groupName);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void invitationrecvd(){
MultiUserChat chatRoom = new MultiUserChat(con, rum);
try {
chatRoom.join(userName);
saveGroupsToDb(userName + Constant.AT + Constant.HOST + Constant.SLASHSMACK, rum, group);
} catch (Exception e) {
e.printStackTrace();
}
}
And This is the group message Listener on home screen
PacketFilter filter = new MessageTypeFilter(Message.Type.groupchat);
groupMessagesListeners = new GroupMessagesListeners();
mConnection.addPacketListener(groupMessagesListeners,filter);
The groupchat is addressed to a XMPP muc (multi user chat) so you would need to join the muc in order to receive messages sent in that particular group. You can read more about this in https://xmpp.org/extensions/xep-0045.html.
Here is an excerpt from the link:
7.2.1 Groupchat 1.0 Protocol
In order to participate in the discussions held in a multi-user chat
room, a user MUST first become an occupant by entering the room. In
the old groupchat 1.0 protocol, this was done by sending presence with
no 'type' attribute to , where "room" is the room
ID, "service" is the hostname of the chat service, and "nick" is the
user's desired nickname within the room:
More or less I already had answered this kind of answer, but your code it's much cleaner (Can't able to receive group chat messages using smack-android:4.1.4).
1) When you create a multiuserchat, to finalize it you must JOIN this chat or the room it's just configurated but not still active.
muc.sendConfigurationForm(submitForm);
muc.join("My Nickname","password"); //omit password if not needed
2) To automatically join your groupchats, you can use PubSub feature
A snippet with Smack can looks like:
BookmarkManager bookmarkManager = BookmarkManager.getBookmarkManager(mConnection);
bookmarkManager.addBookmarkedConference
("My roomname label",
roomName,
true,
"My Nickname",
password);
add this code when:
you create a groupchat
you accept an groupchat's invitation.
(To remove a bookmark, just:
this.bookmarkManager.removeBookmarkedConference(roomName)
)
Finally, after login, add a method to autojoin the groupchat:
List<BookmarkedConference> list = BookmarkManager.getBookmarkManager(mConnection).getBookmarkedConferences();
MultiUserChat muc;
for (BookmarkedConference conference : list)
{
System.out.println("- Conference with bookmark: " + conference.getName() +
" and jid: " + conference.getJid());
if ( (muc = multiUserChatManager.getMultiUserChat(conference.getJid()) ) != null
&& conference.isAutoJoin())
{
muc.join("My Nickname");
//foo
}
}
After this you have all to config and manage your groupchats. Personally I don't like to add to mConnection a generic PacketListener due to the consequent difficoulty to synchronyze messages receveid with front end, but this will be eventually another branch.
Related
I am creating an simple one to one chat app, I've done with the message send and receive. Now I am trying to show the status of the user to another(contacts) like "online/offline" etc. For that I have to use Presence and Roster.But I don't know where and how to use that, I mean the complete flow of subscription request and accept and after the subscription, the status of the users i.e. Online/Offline etc.
First of all you need to send and accept contact request
From Open-fire you can also do it from back-end
Steps :
First click on Users/Groups >> click on "UserName" >> click on roster >> add roster
Here i attach screen of steps
click on add new item
add roster
edit roster and select subscription both
then after you will get roster list using this code
ArrayList<RosterEntry> rosterLists = new ArrayList<>();
public List<RosterEntry> getFriendsList() throws SmackException.NotLoggedInException, InterruptedException, SmackException.NotConnectedException {
rosterLists = new ArrayList<>();
roster = Roster.getInstanceFor(Config.conn1);//connection object of AbstractXMPPConnection
if (!roster.isLoaded()) {
roster.reloadAndWait();
Log.e("Roster :", "Reload and wait");
}
Collection<RosterEntry> entries = roster.getEntries();
Log.e("Size of Roster :", entries.size() + "");
for (RosterEntry entry : entries) {
rosterLists.add(entry);
Log.d("Buddies", "Here: " + entry.toString());
Log.d("Buddies", "User: " + entry.getUser());//get userinfo
Log.d("Buddies", "User Name:" + entry.getName());//get username
Log.d("Buddies", "User Status: " + entry.getStatus());//get status of user
}
listAdapter = new FriendUserListAdapter(UserListActivity.this, rosterLists);
user_list.setAdapter(listAdapter);
return rosterLists;
}
what is the difference between subscription type both and from???
When any user add bot has his/her contact, then in the end of whole process, subscription status of ofRoster(openfire) table is set to ‘from’. The desired result of this process is ‘both’
I've created a login connection succesfully for XMPP with Smack Api(4.1.4). Now i'm trying to create MultiUserChat using,
try {
String myMUCName = "TestGroup";
String myMUCService = "conference.(my local ip)";
String myMUCfullName = myMUCName + "#" + myMUCService;
String userName = "Test5";
MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
MultiUserChat muc = manager.getMultiUserChat(myMUCfullName);
muc.create(userName);
Log.d(LOCAL_TAG, "createGroupChat -- Group CEATED Successfully ");
Form form = muc.getConfigurationForm();
Form submitForm = form.createAnswerForm();
List<FormField> fields = form.getFields();
Log.d(LOCAL_TAG, "createGroupChat -- fields.size(): "+fields.size());
for (int i = 0; i < fields.size(); i++) {
FormField field = (FormField) fields.get(i);
if (!FormField.Type.hidden.equals(field.getType()) && field.getVariable() != null) {
submitForm.setDefaultAnswer(field.getVariable());
}
}
List owners = new ArrayList();
owners.add(userName); //Own user
owners.add("Test7"); //Another user
submitForm.setAnswer("muc#roomconfig_roomowners", owners);
submitForm.setAnswer("muc#roomconfig_publicroom", true);
submitForm.setAnswer("muc#roomconfig_persistentroom", true);
muc.sendConfigurationForm(new Form(DataForm.Type.submit));
//muc.sendConfigurationForm(submitForm);
Log.d(LOCAL_TAG, "createGroupChat -- Sent Configuration");
muc.join(TestGroup);
Log.d(LOCAL_TAG, "createGroupChat -- Group Joined Successfully -- owners.size(): "+owners.size());
But while creating the group i'm getting an exception as
"org.jivesoftware.smack.XMPPException$XMPPErrorException: XMPPError: forbidden - auth".
Hope so, this exception occurs at the code
muc.sendConfigurationForm(submitForm);
which is commented in this for that reason. Because i didn't get the log after that code. To fix that, I have changed that code to
muc.sendConfigurationForm(new Form(DataForm.Type.submit));
which fixes that exception and created me a group, because i could see the log as printed and can see my group in the open fire. But i do know how my selected users for the group gets added, by doing like this, since owners list(or submit form) is not included in this at anywhere. I don't know what's happening in this and I'm not sure that i'm doing right. Plz suggest me to how to proceed. Thanks in advance.
Try this code:
Form form = muc.getConfigurationForm().createAnswerForm();
// Create a new form to submit based on the original form
form.setAnswer("muc#roomconfig_passwordprotectedroom", false);
form.setAnswer("muc#roomconfig_roomname",myMUCName);
form.setAnswer("muc#roomconfig_persistentroom", true);
form.setAnswer("muc#roomconfig_changesubject", true);
form.setAnswer("muc#roomconfig_publicroom",true);
form.setAnswer("muc#roomconfig_allowinvites",true);
form.setAnswer("muc#roomconfig_membersonly",false);
form.setAnswer("muc#roomconfig_moderatedroom",false);
// Sets the new owner of the room
List<String> owners = new ArrayList<String>();
//Be carefull: if members does not exists, it brokes!
owners.add(userName +"#"+"(my local ip or server name placeholder)");
form.setAnswer("muc#roomconfig_roomowners", owners);
// Send the completed form
muc.sendConfigurationForm(form);
System.out.println("MUC is now registered");
muc.join(userName );
Right now, if all it's ok, you'll join the Room as userName and userName will be also the owner.
You'll can check Owners of a MUC programmatically by
muc.getOwners() //List<Affiliate>, for each Affialiate you'll have to affiliate.getJid().toString()
You can invite people by this line of code:
muc.invite(user, "Invite");
And then, if you want to see them "forever",
muc.grantMembership(user);
so you'll be able to see membership with
muc.getMembers();
Please pay attention:
Affiliate: user with a defined role (Onwer, Admin, Member, Outcast) in a MUC
Occupants: user ONLINE in a MUC
Not all Occupants can have a role, not all Affiliates are automatically be occupants.
More, you can't be sure an Affiliate ever joined the groupchat.
Flux it's something like:
Muc Creation by User1
(optional) Muc Invitation by User1 to any user he desire (example: User2, User4)
(optional) Muc Affiliate assignation by User1 to any existant user he desire (example: User3, User4)
User2 and User4 will recive, when online, a invitation to accept/reject
User3 and User4 will not recive nothing, but they will have a role in the MUC.
User2, User3, User4 need to register IQProviders to get IQ Stanzas and then listners for each MUC to recive Invitations, another to recive Messages (and or other events).
For SMACK 4.3.4 and above.
multiUserChatManager = MultiUserChatManager.getInstanceFor(connection);
multiUserChat = multiUserChatManager.getMultiUserChat(JidCreate.entityBareFrom(roomJID));
multiUserChat.create(Resourcepart.from(nickname));
Form form = multiUserChat.getConfigurationForm();
Form submitForm = form.createAnswerForm(); submitForm.getField("muc#roomconfig_publicroom").addValue("1");
submitForm.getField("muc#roomconfig_enablelogging").addValue("1");
submitForm.getField("x-muc#roomconfig_reservednick").addValue("0");
submitForm.getField("x-muc#roomconfig_canchangenick").addValue("0");
submitForm.getField("x-muc#roomconfig_registration").addValue("0");
submitForm.getField("muc#roomconfig_passwordprotectedroom").addValue("0");
submitForm.getField("muc#roomconfig_roomname").addValue(roomName);
submitForm.getField("muc#roomconfig_whois").addValue("participants");
submitForm.getField("muc#roomconfig_membersonly").addValue("1");
submitForm.getField("muc#roomconfig_persistentroom").addValue("1");
multiUserChat.sendConfigurationForm(submitForm);
This is how you can send the room configuration from and create room (MUC).
I want to know how can I achieve the following SQL query on parse,
e.g. assume we have 2 tables/classes in our DB: User, Profile with example values in brackets.
User
- email(tt#tt.com)
- Name(tt)
Profile
-email(tt#tt.com)
-age(23)
Sql query,
select User.email,User.name,Profile.age from User
JOIN Profile on User.email = Profile.email
Where User.email = 'tt#tt.com'
The resulting recordset would be "tt#tt.com,tt,23e".
Now, if I want to make the same thing with Parse, or better, how can I achieve this??
I read about these structures but I don't know if they apply to this case and how to use them. I'm developing in Android
any help would be greatly appreciated.
If you have pointers to _Users on your Class Profile best method would be this one :
var Profile = Parse.Object.extend("Profile");
var query = new Parse.Query(Profile);
query.equalTo("email", request.params.email);
return query.first().then(null, function(error) {
return Parse.Promise.error('Sorry, this profile was not found.');
}).then(function(profile) {
profile.get('_User').fetch().then(function(user) {
console.log(
'name : ' + user.get('name') + ' ' +
'age : ' + profile.get('age')
);
});
});
Note for profile.get('_User') your pointer's name may change and not be _User
Try this solution.
In User class, create a Pointer to Profile. Then you can query from User class to get Profile.
ParseQuery<User> parseQuery = ParseQuery.getQuery("User");
parseQuery.whereEqualsTo("emai", "youremail#mail.com");
parseQuery.getFirstInBackground(new GetCallback<User>() {
public void done(User user, ParseException e) {
if (e != null) {
Log.d("score", "The getFirst request failed.");
return;
}
Profile profile = (Profile) user.get("profile");
}
});
I'm facing an issue in my application where I send the server request once and receive a single response but my request has created duplicate rows in the database. The only primary key in the database table is the row id which gets incremented every time a request is sent so duplicate rows of values get created with different row ids. I'm using Xamarin Android. Could you please let me know if this issue is a bug related to Xamarin and if they is any way in which this can be fixed?
Thank you.
Edit:
This is my code:
I call this method in my OnCreate()
public void SendMobileNo(Activity activity)
{
Services_GetValue.GetValue client = new Services_GetValue.GetValue();
Services_GetValue.GetValueRequest request = new Services_GetValue.GetValueRequest()
{
key = "abac",
PhoneNo = "1234567890"
};
client.BeginCheckPhone(request, (ar) => {
Services_GetValue.GetValueResponse response = client.EndCheckPhone(ar);
this.IsPhoneValid = response.IsValidPhoneNo;
activity.RunOnUiThread (() => {
if (SendMobileNoCompleted != null)
{
this.SendMobileNoCompleted();
this.SendMobileNoCompleted = null;
}
});
}, null);
client.CheckPhone(request);
}
I have created a Proxy in WebReferences package with the name "Services_GetValue.GetValue" and it is a SOAP webservice.
I have download yaxim source code from github yaxim link Now I want to get the member of
conference , I tried below code but its not working,
String room = "test#conference.abc";
Connection xmppConnection;
ConnectionThread connectionThread = AccountManager.getInstance()
.getAccount(account).getConnectionThread();
if (connectionThread == null) {
Application.getInstance().onError(R.string.NOT_CONNECTED);
return true;
}
xmppConnection = connectionThread.getXMPPConnection();
MultiUserChat userChat = new MultiUserChat(xmppConnection, room);
Iterator<String> roomUsers = userChat.getOccupants();
System.out.println("roomUsers count === "+userChat.getOccupantsCount());
while (roomUsers.hasNext()) {
String roomOccupants = (String) roomUsers.next();
System.out.println("room users ==== "+roomOccupants);
}
but roomUsers count returns 0.
if any one know other way for getting users list from conference room , then let me know
You need to join the MUC in order to see its members.