Actually you don’'t have to do anything. Once the other user adds you to his roster you also have him in your roster. If you are not seeing him in your roster you may need to reload the roster with roster.reload(), but this should not be necessary.
Yes, you are right, it doesn’'t work like I said, you must do something else to see the presence of other user.
When user (A) sends a subscribe request to a contact (B), and the contact (B) accepts the subscription, the state is the following (from the RFC 3921):
From the perspective of the user (A), there now exists a subscription to the contact’'s (B) presence information; from the perspective of the contact (B), there now exists a subscription from the user (A).
The important thing is that the contact (B) do not have a subscription to the user (A) presence information.
To do this the contact (B) must send a subscription request to the user (A). If the user (A) accepts this subscription then the state is:
The user (A) and the contact (B) now have a mutual subscription to each other’'s presence – i.e., the subscription is of type “both”.
So going back to the original question you must invoke a connection.getRoster().createEntry() when you receives a subscription request. The hard part is “knowing” when. If you have the subscription mode ACCEPT_ALL you can do this to all the connections:
RosterListener rosterListener = new RosterListener() { public void presenceChanged(String XMPPAddress) {
} public void entriesUpdated(Collection addresses) {
} public void entriesDeleted(Collection addresses) {
} public void entriesAdded(Collection addresses) {
for (Iterator it = addresses.iterator(); it.hasNext();) {
String address = (String) it.next();
RosterEntry entry = conn.getRoster().getEntry(address);
//When the entry is only from the other user, then send a subscription request
if (entry != null && entry.getType() == RosterPacket.ItemType.FROM) {
try {
System.out.println("Creating entry to: " + entry.getUser());
conn.getRoster().createEntry(entry.getUser(), entry.getUser(), new String[0]);
} catch (XMPPException e) {
e.printStackTrace();
}
}
}
} }; conn.getRoster().addRosterListener(rosterListener);
Yap, works perfectly now :-D. But… since this discussion is already underway Did you have any trouble with adding user that didn’'t have you in his roster? Using the A,B notation. User B has user A in his roster (through shared roster defined on the server). User A is a “lesser” user and has to add everyone manually. He adds B and everything works fine. But if there is another “lesser” user C and A wants to add him, he gets modify 406 error. Did you get anything like that? Thanks
Ok, I got it. I get the error when I’'m creating a roster group, whose name is the same as display name of any of the groups defined on the server. No user have to have anything to do with any of those groups, funny enough…