Невозможно получить присутствие в списке с помощью smack, openfire - PullRequest
6 голосов
/ 17 декабря 2009

Я новичок в 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 = 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 alwasys дает «недоступен», в то время как строки № 2 и 3 всегда дают ноль

Я не могу выяснить причину этой проблемы. Пожалуйста, помогите мне решить эту проблему.

Заранее спасибо.

Ответы [ 5 ]

8 голосов
/ 16 сентября 2012

Использование 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)

7 голосов
/ 08 января 2010

проблема в том, что после немедленного входа в систему потребуется некоторое время для обновления информации о присутствии пользователей. Так как между входом в систему и вызовом функции онлайн-друзей должен быть поток thread.sleep () на несколько секунд . Тогда онлайн контакты будут восстановлены. Я сделал это и смог получить их. после входа в систему используйте

Thread.sleep (5000);

используйте в начале метода также

3 голосов
/ 08 января 2010

У меня была такая же проблема, и я некоторое время искал, прежде чем нашел, в чем проблема. На самом деле вам не нужно делать Thread.sleep (). Проблема в том, что у вас нет «разрешения» на получение Присутствия других пользователей.

Чтобы решить эту проблему, просто зайдите в администратор Openfire -> ваши настройки пользователя -> Ростер // Затем просто установите подписку для собеседника, которого вы хотите, чтобы присутствовали «оба» (оба пользователя могут просматривать присутствие друг друга).

Надеюсь, это поможет.

Изменить: На самом деле вам нужно добавить Thread.sleep (), прежде чем получить список из соединения. Без Thread.sleep () иногда это работает, иногда нет ...

2 голосов
/ 01 октября 2015

Я исправил это добавив:

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

после

 Roster roster = Roster.getInstanceFor(connection);

Ссылка: Smack 4.1.0 Android and Roster не отображается

0 голосов
/ 25 октября 2015

Это полный код

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