how to get user online or offline in asmack, andro

2019-04-06 02:25发布

问题:

Possible Duplicate:
XMPP aSmack - How can I get the current user state (offline/online/away/etc.)?

I am developing chat app on Android base on asmack lib. I display all the user on the ListView but I use an image to show online/offline user. But It return offline image only, even the user is online, here is my code

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

回答1:

You can get online and offline friends via RosterListener like i did below and then update listview with new data.

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

            }
        });


回答2:

There is a means to find the offline/online status of the user. It can be done by seeking the PRESENCE OF THE USER. Here is the code snippet :

//here is how you can get is ONLINE or OFFLINE

        Presence availability = roster.getPresence(user);

And here is the code to get its presence mode i.e if user is available then is he AWAY,DONOT DISTURB MODE or ONLINE For CHAT.

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

you can save this state in an array list as :-

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

Please let me know if you have any queries regarding xmpp/smack in chat type application