无法通过使用 smack、openfire 获得名册
Posted
技术标签:
【中文标题】无法通过使用 smack、openfire 获得名册【英文标题】:Unable to get presence of roster by using smack, openfire 【发布时间】:2010-12-27 12:43:22 【问题描述】:我是 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
我无法找出这个问题的原因。请帮我解决这个问题。
提前致谢。
【问题讨论】:
您想要出席的用户是否接受了您的订阅?如果没有,您将无法获得 Presence。 【参考方案1】:这个完整的代码
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());
【讨论】:
【参考方案2】:我修复了它添加:
if (!roster.isLoaded())
roster.reloadAndWait();
之后:
Roster roster = Roster.getInstanceFor(connection);
参考:Smack 4.1.0 android Roster not displaying
【讨论】:
问题不在于条目的问题。问题在于条目的存在。我也遇到了同样的问题。【参考方案3】:使用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)
【讨论】:
这段代码在我的情况下根本不起作用,但我的问题是一样的。请帮助我@Andrea 就像一个魅力 (Y)。当您希望获得联系人的实时通知时,这种方法更可取。否则 thread.sleep() 也是一个解决方案。 (Y) +1。【参考方案4】:我遇到了同样的问题,搜索了一段时间才找到问题所在。实际上,您不需要执行 Thread.sleep()。问题是您没有“权限”来获得其他用户的存在。
要解决这个问题,只需进入 Openfire 管理员 -> 您的用户选项 -> 名册 // 然后只需将您想要获得状态的好友的订阅设置为“两者”(两个用户都可以查看彼此的状态)。
希望对您有所帮助。
编辑:事实上,您需要在从连接中获取名册之前添加一个 Thread.sleep() 。如果没有 Thread.sleep(),有时它可以工作,有时不能......
【讨论】:
【参考方案5】:问题是立即登录后,用户的存在需要一些时间才能更新。所以在登录和调用在线好友函数之间应该有一个thread.sleep()几秒钟.然后将检索在线联系人。我这样做了,并且能够找回它们。 登录后使用
线程.sleep(5000);
也用在方法的开头
【讨论】:
遇到了与原始声明完全相同的问题。按照您的建议,在记录后放置“Thread.sleep(5000)”。像魅力一样工作。谢谢! 为我工作。尽管您需要实现名册列表以实时更新状态。 (Y)。 +1。以上是关于无法通过使用 smack、openfire 获得名册的主要内容,如果未能解决你的问题,请参考以下文章
无法连接到本地 Openfire 服务器(使用 smack api)
使用 smack 从消息存档 openfire 中获取最新对话