Android smack library subscription(not showing inb

2020-03-08 06:24发布

问题:

I am working on an android chat application in which i am using smack library for instant messaging everything is working fine but the huge problem is in subscription.

How to send subscription notification to another user.

Here is my code for sending subscription request:

public void run() {
        /*runOnUiThread(new Runnable() {
            public void run() {*/
                Roster roster = XMPPSmackConnection.getInstance().connection.getRoster();
                roster.setSubscriptionMode(Roster.SubscriptionMode.manual);
                try {
                    if(!_userName.contains("@"))
                        _userName=_userName+"@www.naijapings.net";

                    /*Presence presence = (Presence) packet;
                    Presence presence_request = new Presence(Presence.Type.subscribed);
                    presence_request.setTo(presence.getFrom());
                    presence_request.setType(Presence.Type.subscribed);
                    presence_request.setFrom("current_logged_in_user");
                    XMPPSmackConnection.getInstance().connection.sendPacket(presence_request);
                    roster.createEntry(presence.getFrom(), null, null);*/

                    /*Presence response = new Presence(Presence.Type.subscribe);
                    response.setTo(_userName);
                    XMPPSmackConnection.getInstance().connection.sendPacket(response);*/

                    //PROCESS TWO WAY COMMUNICATION
                    Presence response1 = new Presence(Presence.Type.subscribe);
                    response1.setTo(_userName);
                    XMPPSmackConnection.getInstance().connection.sendPacket(response1);
                    //////////////////////////////////////////////////////

                    //roster.createEntry(_userName, null, null);

                    /*roster.createEntry(_userName, _nickName, Friends);*/
                    //roster.createEntry(_tempUserName, null, null);
                    //roster.createEntry(_userName, _nickName, my_friends[]);
                    //addBuddy(_userName, _nickName, Friends);
                } catch (Exception e) {
                    _progDailog.dismiss();
                    e.printStackTrace();
                }
                _progDailog.dismiss();
                successAlert("Buddy requested successfully");
            /*}
        });*/

The above code only create roster entry to other user's roster list but not showing subscription notification.

Here is code for accepting subscription request:

runOnUiThread(new Runnable() {
                public void run() {
                    try {
                        Roster roster = XMPPSmackConnection.getInstance().connection.getRoster();
                        ///roster.setSubscriptionMode(Roster.SubscriptionMode.manual);
                        //Presence presence = roster.getPresence(_buddyUserName);
                        roster.setSubscriptionMode(Roster.SubscriptionMode.manual);
                        //Presence subscribed = new Presence(Presence.Type.subscribed);

                        Presence response = new Presence(Presence.Type.subscribed);
                        response.setTo(_buddyUserName);
                        XMPPSmackConnection.getInstance().connection.sendPacket(response);

                        /*response = new Presence(Presence.Type.subscribed);
                        response.setTo(_buddyUserName);
                        XMPPSmackConnection.getInstance().connection.sendPacket(response);*/

                        roster.createEntry(_buddyUserName, _nickNameEditText.getText().toString(), Friends);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });

Please suggest the exact scenario.

回答1:

Okay, I toiled hard at this for a couple of days and finally got things working. 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 sends subscribe presence to User2.
  • Roster entry gets automatically created in User1's roster (but not in User2's roster).
  • User2 receives subscribe request from User1.
  • User2 sends back a subscribed presence to User2 (User2 > User1 subscription complete).
  • User2 checks if User1 is in User2's roster. User1 is not in User2's roster. User2 sends back a subscribe presence to User1.
  • Roster entry gets automatically created in User2's roster.
  • User1 receives subscribe presence from User2.
  • 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
                }
            }
    


回答2:

In order to receive subscription requests, you must:

1) Send presence:

<presence/>

2) Retrieve roster:

<iq type='get' id='roster1'>
  <query xmlns='jabber:iq:roster'/>
</iq>

First-time client writers are often surprised by the second one.



回答3:

you can not send subscription like that, do it this way:

 Presence subscription = new Presence(
               Presence.Type.subscribe);
       subscription.setTo(CurrentUser+"@reza-hp");
       subscription.setPriority(24);
       newp.setMode(Presence.Mode.available);
       connection.sendPacket(subscription);