如何在 asmack 和 Android 中获取用户的在线或离线状态

9

可能重复:
XMPP aSmack - 如何获取当前用户状态(离线/在线/离开等)?

我正在基于asmack库开发Android聊天应用。我在ListView上显示所有用户,但是我使用图像来显示在线/离线用户。但是即使用户在线,它也只返回离线图像,这是我的代码:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // setContentView(R.layout.buddies);

    Controller.getInstance().roster = Controller.getInstance().connection.getRoster();
//  ArrayList<Buddy> buddies = new ArrayList<Buddy>();
    Collection<RosterEntry> entries = Controller.getInstance().roster.getEntries();
    Controller.getInstance().buddyList = new Buddy[entries.size()];

    int i = 0;

    for (RosterEntry r : entries) {
        Buddy bud = new Buddy();
        VCard card = new VCard();
        try {
            ProviderManager.getInstance().addIQProvider("vCard",
                    "vcard-temp", new VCardProvider());
            card.load(Controller.getInstance().connection, r.getUser());
        } catch (XMPPException e) {
            Log.e("ChatOnAndroid", e.getMessage() + " " + r.getUser() + " "
                    + e.getLocalizedMessage());
        }
        bud.jid = r.getUser();
        bud.name = r.getName();
        bud.status = Controller.getInstance().roster.getPresence(r.getUser());
        Controller.getInstance().buddies.add(bud);


        Controller.getInstance().buddyList[i++] = bud;
    }
    BuddyAdapter adapter = new BuddyAdapter(this, R.layout.buddy, Controller.getInstance().buddies);

    setListAdapter(adapter);


     /*
      * list = (ListView) findViewById(R.id.buddiesList);
     * list.setAdapter(adapter);
     */
}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {     
    startActivity(new Intent(this, Conferences.class));
}

public class BuddyAdapter extends ArrayAdapter<Buddy> {

    private ArrayList<Buddy> items;

    public BuddyAdapter(Context context, int textViewResourceId,
            ArrayList<Buddy> items) {
        super(context, textViewResourceId, items);
        this.items = items;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.buddy, null);
        }
        Buddy buddy = items.get(position);

        if (buddy != null) {
            TextView tt = (TextView) v.findViewById(R.id.buddyName);
            ImageView iv = (ImageView) v.findViewById(R.id.buddyThumb);
            //buddy.status = Controller.getInstance().roster.getPresence(buddy.jid);

            if (buddy.status != null) {
                buddy.img = R.drawable.status_online;
                iv.setImageResource(buddy.img);
            } else if (buddy.status == null) {
                buddy.img = R.drawable.status_offline;
                iv.setImageResource(buddy.img);
            }

            //iv.setImageResource(buddy.img);
            if (tt != null) {
                tt.setText(buddy.name);
            }
        }
        return v;
    }
}
2个回答

0

你可以通过RosterListener获取在线和离线的好友,就像我下面所做的那样,然后使用新数据更新listview。

roster.addRosterListener(new RosterListener() {

            @Override
            public void presenceChanged(final Presence presence) {

                System.out.println("Presence changed: " + presence.getFrom()
                        + " " + presence);

                runOnUiThread(new Runnable() {
                    public void run() {

                        // / To Update listview  should clear arraylists first
                        // then inavalidate Listview to redraw then add new data
                        // to Arraylists then notify adapter.
                        JID.clear();
                        Names.clear();
                        Status.clear();
                        Image.clear();
                        list.invalidateViews();
                        for (RosterEntry entry : entries) {
                            card = new VCard();
                            presencek = roster.getPresence(entry.getUser());

                            try {
                                card.load(Main.conn, entry.getUser());
                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                            JID.add(entry.getUser());
                            Names.add(card.getField("FN"));
                            Status.add(presencek.getType().name());
                            Log.d("Prescence", "" + presencek.getType().name());// //num
                                                                                // one
                                                                                // log

                            // if (bud.name == null)
                            // bud.name = bud.jid;
                            // buddies.add(bud);
                            byte[] img = card.getAvatar();
                            if (img != null) {
                                int len = img.length;
                                Image.add(BitmapFactory.decodeByteArray(img, 0,
                                        len));
                            } else {
                                Drawable d = getApplicationContext()
                                        .getResources().getDrawable(
                                                R.drawable.save);
                                Bitmap bitmap = ((BitmapDrawable) d)
                                        .getBitmap();
                                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                                bitmap.compress(Bitmap.CompressFormat.PNG, 100,
                                        stream);
                                img = stream.toByteArray();
                                int len = img.length;
                                Image.add(BitmapFactory.decodeByteArray(img, 0,
                                        len));
                                // Image.add(null);
                            }
                            // buddyList[i++] = bud;
                        }

                        adapter.notifyDataSetChanged();


                }       

            @Override
            public void entriesUpdated(Collection<String> addresses) {
                // TODO Auto-generated method stub

            }

            @Override
            public void entriesDeleted(Collection<String> addresses) {
                // TODO Auto-generated method stub

            }

            @Override
            public void entriesAdded(Collection<String> addresses) {
                // TODO Auto-generated method stub

            }
        });

我也遇到了同样的问题,我能够从花名册中获取所有好友列表,现在我的任务是如何只获取在线用户并在列表视图中显示,你能指导一下吗? - Ali Ashiq

0

有一种方法可以查找用户的离线/在线状态。这可以通过寻找用户的存在来完成。以下是代码片段:

//以下是如何获取在线或离线状态的代码

        Presence availability = roster.getPresence(user);

以下是获取用户在线状态的代码,即如果用户在线,则他处于离开、勿扰或在线聊天模式。

public int retrieveState_mode(Mode userMode, boolean isOnline) {
        int userState = 0;
        /** 0 for offline, 1 for online, 2 for away,3 for busy*/
        if(userMode == Mode.dnd) {
            userState = 3;
        } else if (userMode == Mode.away || userMode == Mode.xa) {

            userState = 2;
        } else if (isOnline) {
            userState = 1;
        }
        return userState;
    }

你可以将此状态保存在数组列表中,如下所示:

mFriendsDataClass.friendState = retrieveState_mode(availability.getMode(),availability.isAvailable());

如果您在聊天类型应用程序中有任何关于XMPP/Smack的疑问,请告诉我。


我尝试了你的代码片段,但即使另一端设备显示我在线,我仍然得到了用户不可用的错误。 - Terril Thomas
请发布您的代码片段示例,上述代码对我来说完美运行,如果没有看到您手头的代码,我无法发表任何意见或建议。 - Gaurav Arora
私有的Presence presence;(全局定义)presence = roster.getPresence(emailId.get(i)); Mode userMode = presence.getMode(); int userInstance = retrieveStateMode(userMode, presence.isAvailable()); - Terril Thomas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接