6

私は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() が必要です。オンラインの連絡先が取得されます。私はそれを行い、それらを取得することができました。ログイン後利用

Thread.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 に答える