6

I am new to smack API. I am trying to develop a chat application where I was trying for setting and getting the presence.

When I change the presence of a user, its working perfectly fine and it is getting reflected in the Openfire Server.

But when I tries to get the Presence of a user, I am always getting the status as 'unavailable' even if his presence in openfire is showing as 'available'.

I am using the following code to set the status.

        Presence presence = new Presence(Presence.Type.available);
        presence.setStatus("Online, Programmatically!");
        presence.setPriority(24);
        presence.setMode(Presence.Mode.available);
        user.getConnection().sendPacket(presence);

I am using the Roster class to get the presence as follows.

Roster roster = avatar.getRoster();
Collection<RosterEntry> entries = roster.getEntries();

for(RosterEntry rosterEntry: entries) {
    String user = rosterEntry.getUser();

    Presence presence = roster.getPresence(user);

    System.out.println("Presence : "+presence);                                     // 1
    System.out.println("Presence type: "+presence.getType());                // 2
    System.out.println("Presence mode: "+presence.getMode());             // 3

}

Line No 1 alwasys gives 'unavailable' while line number 2 and 3 always give null

I am not able to figure out the cause of this problem. Please help me to resolve this issue.

Thanks in advance.

Trung Nguyen
  • 7,442
  • 2
  • 45
  • 87
Le Hoang Long
  • 61
  • 1
  • 1
  • 3

5 Answers5

8

Using RosterListener is the proper solution to this problem. There is no reason that code should have a Thread.sleep() in order to make it work properly.

Roster roster = con.getRoster();
roster.addRosterListener(new RosterListener() {
    // Ignored events public void entriesAdded(Collection<String> addresses) {}
    public void entriesDeleted(Collection<String> addresses) {}
    public void entriesUpdated(Collection<String> addresses) {}
    public void presenceChanged(Presence presence) {
        System.out.println("Presence changed: " + presence.getFrom() + " " + presence);
    }
});

(source: http://www.igniterealtime.org/builds/smack/docs/latest/documentation/roster.html)

Andrea Motto
  • 1,540
  • 21
  • 38
  • this code is not working at all in my case but my problem is same. please help me @Andrea – Gaurav Arora Oct 09 '12 at 11:04
  • worked like a charm (Y). This approach is preferable when you want get real time notifications for your contacts. Otherwise thread.sleep() is also a solution. (Y) +1. – N-JOY Jun 25 '14 at 19:45
7

the problem is that after logging in immediately, it is gonna take some time for the presence of users to get updated.So between logging in and calling the online buddies function there should be a thread.sleep() for a few seconds.Then the online contacts will be retrieved. I did that and was able to retrieve them. after login use

Thread.sleep(5000);

use in the beginiing of the method also

ravi
  • 79
  • 1
  • Had the exact same problem as in the original statement. Put "Thread.sleep(5000)" after logging is as suggested by you. Worked like a charm. Thanks ! – Vini Apr 06 '11 at 10:26
  • worked for me. though you need to implement Roster lister for real time update for presence. (Y). +1. – N-JOY Jun 25 '14 at 19:46
3

I had the same problem and searched for a while before finding what the problem was. In fact, you don't need to do a Thread.sleep(). The problem is that you don't have the "permission" to get the Presence of other users.

To solve the problem, just go in Openfire admin -> your user options -> Roster // Then just set the subscription of the buddy you wanna get the presence to "both" (both users can view each other presence).

Hope that is helps.

Edit : In fact you need to add a Thread.sleep() before getting the roster from the connection. Without the Thread.sleep(), sometimes it works, sometimes not...

2

I fixed it adding:

 if (!roster.isLoaded()) 
  roster.reloadAndWait();

after:

 Roster roster = Roster.getInstanceFor(connection);

Ref: Smack 4.1.0 android Roster not displaying

Community
  • 1
  • 1
mac
  • 627
  • 1
  • 9
  • 21
  • The question is not about problem with entries.. The problem is with the Presence of entries. I am also having exactly the same issue. – Dila Gurung Nov 19 '15 at 10:22
0

This full code

 public void getRoaster(final Callback<List<HashMap<String, String>>> callback) {
    final Roster roster = Roster.getInstanceFor(connection);
    boolean success = true;

    if (!roster.isLoaded())
        try {
            roster.reloadAndWait();
        } catch (SmackException.NotLoggedInException | SmackException.NotConnectedException | InterruptedException e) {
            android.util.Log.e(AppConstant.PUBLIC_TAG, TAG + " " + e.getMessage());
            success = false;
        }

    if (!success) {
        if (callback != null) {
            callback.onError(new Throwable());
        }
    }

    Collection<RosterEntry> entries = roster.getEntries();
    List<HashMap<String, String>> maps = new ArrayList<HashMap<String, String>>(entries.size());
    for (RosterEntry entry : entries) {
        HashMap<String, String> map = new HashMap<String, String>(3);
        Presence presence = roster.getPresence(entry.getUser());

        map.put(ROASTER_KEY, entry.getName());
        map.put(ROASTER_BARE_JID, entry.getUser());
        map.put(PRESENCE_TYPE, presence.isAvailable() == true ? PRESENCE_ONLINE : PRESENCE_OFFLINE);
        maps.add(map);
    }

    if (maps != null && maps.size() > 0 && callback != null) {
        callback.onSuccess(maps);
    } else {
        callback.onError(new Throwable());
    }
}
raditya gumay
  • 2,951
  • 3
  • 17
  • 24