6

我是 smack API 的新手。我正在尝试开发一个聊天应用程序,我正在尝试设置和获取存在。

当我更改用户的存在时,它工作得非常好,并且它会反映在 Openfire 服务器中。

但是,当我尝试获取用户的存在时,我总是将状态设为“不可用”,即使他在 openfire 中的存在显示为“可用”。

我正在使用以下代码来设置状态。

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

我正在使用 Roster 类来获得如下存在。

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

}

第 1 行总是给出“不可用”,而第 2 行和第 3 行总是给出 null

我无法弄清楚这个问题的原因。请帮我解决这个问题。

提前致谢。

4

5 回答 5

8

使用RosterListener是解决此问题的正确方法。没有理由代码应该有一个Thread.sleep()以使其正常工作。

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

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

于 2012-09-15T23:59:01.203 回答
7

问题是立即登录后,用户的存在需要一些时间才能更新。所以在登录和调用在线好友函数之间应该有一个thread.sleep()几秒钟。然后将检索在线联系人。我这样做了,并且能够找回它们。登录后使用

线程.sleep(5000);

在方法开始时也使用

于 2010-01-08T06:33:13.880 回答
3

我遇到了同样的问题并搜索了一段时间才找到问题所在。事实上,您不需要执行 Thread.sleep()。问题是您没有“权限”来获得其他用户的存在。

要解决这个问题,只需进入 Openfire 管理员 -> 您的用户选项 -> 名册 // 然后只需将您想要的好友的订阅设置为“两者”(两个用户都可以查看彼此的状态)。

希望这会有所帮助。

编辑:事实上,您需要在从连接中获取名册之前添加一个 Thread.sleep() 。如果没有 Thread.sleep(),有时它可以工作,有时不能......

于 2010-01-08T09:44:23.703 回答
2

我修复了它添加:

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

后:

 Roster roster = Roster.getInstanceFor(connection);

参考:Smack 4.1.0 android 名册未显示

于 2015-10-01T07:56:00.113 回答
0

这个完整的代码

 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());
    }
}
于 2015-10-25T06:39:43.897 回答