i\'m using smack 3.1.0, and when i add a roster,i can\'t get subscription \"both\". who can help me? below is my code:
Roster.setDefaultSubscriptionMode(Rost
Both users need to subscribe to each other. By sending a presence subscription stanza. In Smack:
Presence presence = new Presence(Presence.Type.subscribe);
presence.setTo(jid);
connection.sendPacket(presence);
Section 3.1 of the RFC6121 will give you the semantic details.
Okay, I toiled hard at this for a couple of days and finally got things working. Thank you @Joe Hildebrand, your answer put me on the right track to solve this. I have implemented it with a manual subscription mode (ie. user needs to accept another user's request manually).
The server keeps pushing subscribe request to the user (upon re-login) if the user hasn't sent a subscribed or unsubscribed back. So what you can do is save the incoming subscribe requests locally in a list and display that as a "friend request list" for manual accept/reject. If your application gets restarted (and hence re-connects to server), the server will push subscribe requests again.
This is how it works:
User1 checks if User2 is in User1's roster. User2 is in User1's roster. User1 sends back a subscribed presence to User2 (User2 > User1 subscription complete).
final Presence newPresence = (Presence) packet;
final Presence.Type presenceType = newPresence.getType();
final String fromId = newPresence.getFrom();
final RosterEntry newEntry = getRoster().getEntry(fromId);
if (presenceType == Presence.Type.subscribe)
{
//from new user
if (newEntry == null)
{
//save request locally for later accept/reject
//later accept will send back a subscribe & subscribed presence to user with fromId
//or accept immediately by sending back subscribe and unsubscribed right now
}
//from a user that previously accepted your request
else
{
//send back subscribed presence to user with fromId
}
}
Rewriting @mschonaker's answer to be a little more clear.
Both users need to subscribe to each other and accept the subscription request they received. Let's call them Alice and Bob. Alice sends a subscription request to Bob:
Presence subscribe = new Presence(Presence.Type.subscribe);
subscribe.setTo('bob@example.com');
connection.sendPacket(subscribe);
When Bob receives the request, he approves it:
Presence subscribed = new Presence(Presence.Type.subscribed);
subscribed.setTo('alice@example.com');
connection.sendPacket(subscribed);
Bob may also be interested in Alice's presence, so he subscribes to her:
Presence subscribe = new Presence(Presence.Type.subscribe);
subscribe.setTo('alice@example.com');
connection.sendPacket(subscribe);
And Alice needs to approve Bob's request:
Presence subscribed = new Presence(Presence.Type.subscribed);
subscribed.setTo('bob@example.com');
connection.sendPacket(subscribed);
Section 3.1 of RFC6121 is the current best reference for how this works.
If you are using open fire server you can also use User Service plugin which will create roster with subscription both...
Same problem I was face but I got the solution how subscribe set 'both'
Below is sending subscription to user, when you added the user
Presence pres = new Presence(Presence.Type.subscribed);
pres.setPriority(24);
pres.setMode(Presence.Mode.available);
pres.setTo(friendJid);
RoosterConnection.getConnection().sendStanza(pres);
and Receiving end put below method in connection class and presenceChanged is default method of RosterListener.
@Override
public void presenceChanged(Presence presence) {
mBus.post(presence);
try {
Presence pres = new Presence(Presence.Type.subscribed);
pres.setTo(presence.getFrom());
RoosterConnection.getConnection().sendStanza(pres);
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}