Unable to get presence of roster by using smack, openfire

天大地大妈咪最大 提交于 2020-01-01 09:57:14

问题


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.


回答1:


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)




回答2:


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




回答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...




回答4:


I fixed it adding:

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

after:

 Roster roster = Roster.getInstanceFor(connection);

Ref: Smack 4.1.0 android Roster not displaying




回答5:


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());
    }
}


来源:https://stackoverflow.com/questions/1919489/unable-to-get-presence-of-roster-by-using-smack-openfire

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!