如何在asmack,android中让用户在线或离线[重复]

Posted

技术标签:

【中文标题】如何在asmack,android中让用户在线或离线[重复]【英文标题】:how to get user online or offline in asmack, android [duplicate] 【发布时间】:2012-02-06 04:39:45 【问题描述】:

可能重复:XMPP aSmack - How can I get the current user state (offline/online/away/etc.)?

我正在基于 asmack lib 在 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;
    

【问题讨论】:

【参考方案1】:

您可以像我在下面那样通过 RosterListener 获取在线和离线朋友,然后使用新数据更新列表视图。

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

            
        );

【讨论】:

我也面临同样的问题,我现在可以从名册中获取所有 buddyList,我的任务是如何只获取在线用户并在列表视图中显示,请您指导我【参考方案2】:

有一种方法可以找到用户的离线/在线状态。它可以通过寻求用户的存在来完成。这是代码 sn-p :

//这里是在线或离线的获取方式

        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 有任何疑问,请告诉我

【讨论】:

我尝试了你的 sn-p,但我让用户不可用,即使另一端设备让我在线 请发布您的示例代码 sn-p,上面的代码对我来说非常完美,如果不查看您的代码,我无法说出或建议任何内容 私人 Presence 出席;(全球定义)出席 = roster.getPresence(emailId.get(i));模式 userMode = presence.getMode(); int userInstance = retrieveStateMode(userMode, presence.isAvailable());

以上是关于如何在asmack,android中让用户在线或离线[重复]的主要内容,如果未能解决你的问题,请参考以下文章

我如何在 php、mysql 和 ajax 的会话中显示用户在线或离线

如何使用 asmack 在 android 中创建多用户聊天应用程序

具有所有者权限的多用户聊天室加入 android + asmack

如何在线保存/加载数据(使用 AJAX 和 JSON 存储数据)和离线(本地)

使用 asmack 更改 XMPP 注册用户密码

在android中使用asmack获取错误的请求400错误