How to get member of conference in xmpp? - android

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.

Related

Not Recieving Messages for MultiUser Chat Xmpp samck android

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.

Getting "$XMPPErrorException: XMPPError: forbidden - auth" error while creating MultiUserChat

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).

Update Azure SQL database failure

I'm using Azure Mobile Services with an android application which I am trying to get working with a SQL database in Azure. Im using a server-side JavaScript function within Mobile Services to handle the insertion and update of data. Insertion of new data operates correctly, however I cannot update any rows with the function.
The error I received is: 409 - error: Could not insert the item because an item with that id already exists.
It seems as though it is trying to insert instead of update, but I can't figure out the solution. Help is much appreciated!
Here's my server-side script from Azure:
function insert(item, user, request) {
var table = tables.getTable('Reviews');
table.where({
text: item.id
}).read({
success: upsertItem
});
function upsertItem(existingItems) {
if (existingItems.length == 0) {
item.numReviews = 1;
item.rating = item.reviews;
request.execute();
} else {
item.id = existingItems[0].id;
item.numReviews = existingItems[0].numReviews + 1;
var average = existingItems[0].reviews / item.numReviews;
item.reviews = existingItems[0].reviews + item.reviews;
item.rating = average;
table.update(item, {
success: function(updatedItem) {
request.respond(200, updatedItem)
}
});
}
}
}
For your initial query, you want to query by the id field:
table.where({
id: item.id
}).read({
success: upsertItem
});

Duplicates getting inserted in database when calling the server in Xamarin Android?

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.

Better way to write a join query in ormlite

I have two tables CustomerBalance and Customer which are bound with CustomerRefId field.
I want the CustomerBalance records that are lets say greater than 100 for a field balance of this tables. I also want to include into my results the name of the particular customer that fulfills that criteria. I created the following method that works!
public List<CustomerBalance> getCustomerBalanceFilter(String filterVal) {
try {
PreparedQuery<CustomerBalance> preparedQuery = mDbHelper.getCustomerBalanceDao().queryBuilder()
.where().gt(CustomerBalance.DB_COL_CUSTOMER_BALANCE, filterVal)
.prepare();
List<CustomerBalance> result = mDbHelper.getCustomerBalanceDao().query(preparedQuery);
for(CustomerBalance alert : result) {
PreparedQuery<Customer> getCustQuery = mDbHelper.getCustomerDao().queryBuilder()
.where().eq(Customer.DB_COL_CUSTOMER_REF_ID, alert.getCustomerID())
.prepare();
List<Customer> customer = mDbHelper.getCustomerDao().query(getCustQuery);
alert.setCustomer(customer.size() == 1 ? customer.get(0) : null);
}
return result;
} catch(Exception ex) {
return null;
}
}
This methods is working, is this the best way to write such a query? or is there a more appropriate approach?
One improvement to your query is to use ORMLite's SelectArg to pass in the customer-id instead of a new query each time. Something like:
...
List<CustomerBalance> result = mDbHelper.getCustomerBalanceDao()
.query(preparedQuery);
SelectArg custIdArg = new SelectArg();
PreparedQuery<Customer> getCustQuery = mDbHelper.getCustomerDao().queryBuilder()
.where().eq(Customer.DB_COL_CUSTOMER_REF_ID, custIdArg)
.prepare();
for (CustomerBalance alert : result) {
custIdArg.setValue(alert.getCustomerID());
List<Customer> customer = mDbHelper.getCustomerDao().query(getCustQuery);
alert.setCustomer(customer.size() == 1 ? customer.get(0) : null);
}
Here are the docs for SelectArg:
http://ormlite.com/docs/select-arg
FYI, there also is an UpdateBuilder, but I don't see an easy way to turn your code above into a single UPDATE statement.

Categories

Resources