ASmack4.0.7详细讲解

Posted 马世豪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ASmack4.0.7详细讲解相关的知识,希望对你有一定的参考价值。

公司最近想做一个聊天软件,就选用了Openfire服务器,Asmack,下面就跟着自己的进度来写一些Asmack的基本方法,会不断跟进.由于网上对于Asmack的新版本的讲解不是太多,并且自己英语水平有限,就花了400大洋在网上买了一篇教程.自己的理解水平也是有限,大家如果有什么好的建议可以下面评论.大家共勉.开始

因为对于Asmack的操作函数,用到的会很多,所以说,对Asmack做了一个工具类.将所有的操作都放到一个XmppConnection.java中.

开启连接.

TODO:无论进行什么什么样的操作,包括,登录,注册,添加好友,前提都需要进行 连接(openConnection)

openConnection();

/**
     * TODO
     * @author mashihao
     * @time 2016/6/16 9:52
     * @return flag 链接开启的标识.
    */


//TODO 老版本的Asmack 需要配置 配置各种Provider,如果不配置,则会无法解析数据但是4.*没有了这个方法
    public boolean openConnection() {

        try {
            ConnectionConfiguration config = new ConnectionConfiguration(Constant.SERVER_HOST, Constant.SERVER_PORT
                    , Constant.SERVER_NAME);
            //设置可以重新连接
            config.setReconnectionAllowed(true);
            //设置安全模式
            config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
            //连接标示
            config.setSendPresence(true);
            //这一个方法和Asmack的老版本不是太一样.
            SASLAuthentication.supportSASLMechanism("PLAIN", 0);
            connection = new XMPPTCPConnection(config);
            connection.connect();
            return true;
        } catch (XMPPException e1) {
            e1.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        } catch (SmackException e1) {
            e1.printStackTrace();
        }
        return false;
    }

登录.

首先呢先看下效果图.登录.gif

login(String username,String password);

    /**
     * @author msh
     * @time 2016/6/16 9:56
     * TODO 登录
     * @param username
     * @param password
     * @return Boolean flag
     */

    public boolean login(String username, String password) {
        try {
            if (getConnection() == null) {
                return false;
            }
            //已连接, 未认证!
            if (!getConnection().isAuthenticated() && getConnection().isConnected()) {
                getConnection().login(username, password);
                //更改在线状态
                Presence presence = new Presence(Presence.Type.available);
                presence.setMode(Presence.Mode.available);
                getConnection().sendPacket(presence);
                return true;
            }


        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return false;
    }

Asmack的耗时工具类(效果就是登陆的时候闪现的等待)

Asmack中的方法,都是耗时操作,所以说都需要开线程执行,如果在Activity中插入大量的Handle,Thread,AsyncTask,都不是太好看,所以这里就做了一个工具类.用于所有的耗时操作.里面加入了一个ProgressDialog,提示用户等待.

XmppLoadThread.java


/**
 * Created by sv-004 on 2016/6/15.
 */
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
/**
 * TODO 使用异步线程工具, AsyncTask,调用Load,result.
 * @author mashihao
 * @time 2016/6/15 20:33
*/
public abstract class XmppLoadThread {
    boolean isHint;
    ProgressDialog mdialog;
    private Context c;
    @SuppressLint("NewApi")
    public XmppLoadThread(Context _mcontext) {
        isHint = true;
        c = _mcontext;
        new AsyncTask<Void, Integer, Object>() {
            @Override
            protected Object doInBackground(Void... arg0) {
                return load();
            }
            @Override
            protected void onPostExecute(Object result) {
                if (isHint && (mdialog == null || !mdialog.isShowing())) {
                    return;
                } else {
                    try {
                        result(result);
                        if (isHint && (mdialog != null && mdialog.isShowing())) {

                            mdialog.dismiss();

//                          mdialog.dismiss();
                        }
                    } catch (Throwable e) {
                        e.printStackTrace();
                    }
                }
            }
            @Override
            protected void onPreExecute() {
                if (isHint) {
                    try {
                        mdialog =  ProgressDialog.show(c, "提示", "正在加载......");
                        mdialog.setCancelable(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }.execute();
    }
    protected abstract Object load();
    protected abstract void result(Object object);
}

源码戳我

里面包含一个圆角头像的实现


之前因为继续看视频就停更了!现在继续


注册

注册的实现

首先Asmack4.0.*之后对Register做了些许修改,改动不是太大,主要在于下面两点

  1. 对于注册时提交UserName,PassWrod的方式不同
//之前提交UserName,PassWrod
        Registration reg = new Registration();
        reg.setType(IQ.Type.SET);
        reg.setTo(getConnection().getServiceName());
        reg.setUsername(account);
        reg.setPassword(password);

//4.0.*之后
        Registration reg = new Registration();
        reg.setType(IQ.Type.SET);
        Map<String, String> attributes = new HashMap<String, String>();
        reg.setTo(connection.getHost());
        attributes.put("username", username);
        attributes.put("password", password);
        reg.setAttributes(attributes);
 2.  获取应答超时方式变化
    SmackConfiguration.getPacketReplyTimeout()
替换为
    connection.getPacketReplyTimeout()
或者
    SmackConfiguration.getDefaultPacketReplyTimeout();

注册

/**
     * 注册
     *
     * @param account
     *            注册帐号
     * @param password
     *            注册密码
     * @return 1、注册成功 0、服务器没有返回结果2、这个账号已经存在3、注册失败
     */
    public IQ regist(String account, String password) {
        if (getConnection() == null)
            return null;
        Registration reg = new Registration();
        reg.setType(IQ.Type.SET);
        Map<String, String> attributes = new HashMap<String, String>();
        reg.setTo(connection.getHost());
        attributes.put("username", username);
        attributes.put("password", password);
        //attributes.put("name", "name");
        reg.setAttributes(attributes);
//      reg.addAttribute("android", "geolo_createUser_android");
        PacketFilter filter = new AndFilter(new PacketIDFilter(reg.getPacketID()), new PacketTypeFilter(IQ.class));

        PacketCollector collector = getConnection().createPacketCollector(filter);
        // 给注册的Packet设置Listener,因为只有等到正真注册成功后,我们才可以交流
        // collector.addPacketListener(packetListener, filter);
        // 向服务器端,发送注册Packet包,注意其中Registration是Packet的子类
        getConnection().sendPacket(reg);
        IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
        // 停止从队列中等待
        collector.cancel();
        return result;
    }

Asmack中离线消息的实现

在网上找了好多的资料,总结出三种不同的方法
  1. 在你需要显示当前的聊天的Activity中,实现PacketListener,并且重写 public void processPacket(Packet packet)在方法中实现你的业务逻辑(将接收到的消息进行处理)
  2. 和第一种很像的就是,自定义一个XmppMessageListener同样需要实现PacketListener,并重写public void processPacket(Packet packet)
    不同的是,这种方法不需要在ChatActivity实现接口,而是在
    ConnectionConfiguration中配置过滤器和监听器.实现
connection.addPacketInterceptor(xmppMessageInterceptor,new PacketTypeFilter(Message.class));
                connection.addPacketListener(messageListener,new PacketTypeFilter(Message.class));
                connection.addPacketListener(new XmppPresenceListener(), new PacketTypeFilter(Presence.class));
                connection.addPacketInterceptor(new XmppPresenceInterceptor(), new PacketTypeFilter(Presence.class));

3 . 不同于上面的两种方法,这种方法是直接通过OfflineMessageManager的getMessages(); 来获取Message对象

/**
     * TODO 获取离线的消息
     *
     * @return List<org.jivesoftware.smack.packet.Message> 返回Message对象
     */
    public static List<org.jivesoftware.smack.packet.Message> getOffLine() {
        List<org.jivesoftware.smack.packet.Message> msglist = new ArrayList<org.jivesoftware.smack.packet.Message>();
        // 获取离线消息,线程阻塞 不能Toast
        try {
            Iterator<org.jivesoftware.smack.packet.Message> it = XmppTool
                        .getOffLineMessageManager().getMessages();
            while (it.hasNext()) {
                org.jivesoftware.smack.packet.Message message = it.next();
                msglist.add(message);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // 设置在线

                Presence presence = new Presence(Presence.Type.available);
                XmppTool.getConnection().sendPacket(presence);
                XmppTool.getOffLineMessageManager().deleteMessages();
            } catch (XMPPException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return msglist;
    }

突然发现这样写太麻烦了,,,,,,,,不写了.

package com.d3.d3xmpp.xmpp;

import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.util.Log;


import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketIDFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Registration;
import org.jivesoftware.smack.packet.RosterPacket.ItemType;
import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smack.provider.PrivacyProvider;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.Form;
import org.jivesoftware.smackx.FormField;
import org.jivesoftware.smackx.GroupChatInvitation;
import org.jivesoftware.smackx.PrivateDataManager;
import org.jivesoftware.smackx.ReportedData;
import org.jivesoftware.smackx.ReportedData.Row;
import org.jivesoftware.smackx.bytestreams.socks5.provider.BytestreamsProvider;
import org.jivesoftware.smackx.muc.DiscussionHistory;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.packet.ChatStateExtension;
import org.jivesoftware.smackx.packet.LastActivity;
import org.jivesoftware.smackx.packet.OfflineMessageInfo;
import org.jivesoftware.smackx.packet.OfflineMessageRequest;
import org.jivesoftware.smackx.packet.SharedGroupsInfo;
import org.jivesoftware.smackx.packet.VCard;
import org.jivesoftware.smackx.provider.AdHocCommandDataProvider;
import org.jivesoftware.smackx.provider.DataFormProvider;
import org.jivesoftware.smackx.provider.DelayInformationProvider;
import org.jivesoftware.smackx.provider.DiscoverInfoProvider;
import org.jivesoftware.smackx.provider.DiscoverItemsProvider;
import org.jivesoftware.smackx.provider.MUCAdminProvider;
import org.jivesoftware.smackx.provider.MUCOwnerProvider;
import org.jivesoftware.smackx.provider.MUCUserProvider;
import org.jivesoftware.smackx.provider.MessageEventProvider;
import org.jivesoftware.smackx.provider.MultipleAddressesProvider;
import org.jivesoftware.smackx.provider.RosterExchangeProvider;
import org.jivesoftware.smackx.provider.StreamInitiationProvider;
import org.jivesoftware.smackx.provider.VCardProvider;
import org.jivesoftware.smackx.provider.XhtmlExtensionProvider;
import org.jivesoftware.smackx.search.UserSearch;
import org.jivesoftware.smackx.search.UserSearchManager;
import org.xmlpull.v1.XmlPullParser;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * TODO XMPP工具类
 * @author msh
 * @time 2016/7/1 15:44
*/
public class XmppConnection {

    private static XMPPConnection connection = null;
    private static XmppConnection xmppConnection;
    public Roster roster;
    private static Chat newchat;
    private static MultiUserChat mulChat;
    private static List<Friend> friendList = new ArrayList<Friend>();
    private XmppConnecionListener connectionListener;
    private XmppMessageInterceptor xmppMessageInterceptor;
    private XmppMessageListener messageListener;
    public static List<Room> myRooms = new ArrayList<Room>();
    public static List<Room> leaveRooms = new ArrayList<Room>();

    static {
        try {
            Class.forName("org.jivesoftware.smack.ReconnectionManager");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 单例模式
     *
     * @return
     */
    public static XmppConnection getInstance() {
        if (xmppConnection == null) {
            xmppConnection = new XmppConnection();
        }
        return xmppConnection;
    }

    public void setNull(){
        connection = null;
    }

    /**
     * 创建连接
     */
    public XMPPConnection getConnection() {
        if (connection == null) {
            openConnection();
        }
        return connection;
    }

    /**
     * 打开连接
     */
    public boolean openConnection() {
        try {
            //如果XMPPConnection 对象已经创建,并且已经验证通过
            if (null == connection || !connection.isAuthenticated()) {
                // 开启DEBUG模式
                XMPPConnection.DEBUG_ENABLED = true;
                // 配置连接
                ConnectionConfiguration config = new ConnectionConfiguration(Constants.SERVER_HOST,
                        Constants.SERVER_PORT, Constants.SERVER_NAME);
//              if (Build.VERSION.SDK_INT >= 14) {
//                  config.setKeystoreType("AndroidCAStore"); //$NON-NLS-1$
//                  config.setTruststorePassword(null);
//                  config.setKeystorePath(null);
//              } else {
//                  config.setKeystoreType("BKS"); //$NON-NLS-1$
//                  String path = System.getProperty("javax.net.ssl.trustStore"); //$NON-NLS-1$
//                  if (path == null)
//                      path = System.getProperty("java.home") + File.separator //$NON-NLS-1$
//                              + "etc" + File.separator + "security" //$NON-NLS-1$ //$NON-NLS-2$
//                              + File.separator + "cacerts.bks"; //$NON-NLS-1$
//                  config.setKeystorePath(path);
//              }
                // config.setSASLAuthenticationEnabled(false);
                //是否允许 进行重连
                config.setReconnectionAllowed(true);
                config.setSecurityMode(SecurityMode.disabled);
                config.setSASLAuthenticationEnabled(false);
                // 状态设为离线,目的为了取离线消息
                config.setSendPresence(true);
                connection = new XMPPConnection(config);
                connection.connect();// 连接到服务器
                // 配置各种Provider,如果不配置,则会无法解析数据
                configureConnection(ProviderManager.getInstance());
                // 添加连接监听
                connectionListener = new XmppConnecionListener();
                connection.addConnectionListener(connectionListener);
                xmppMessageInterceptor = new XmppMessageInterceptor();
                messageListener = new XmppMessageListener();


                connection.addPacketInterceptor(xmppMessageInterceptor,new PacketTypeFilter(Message.class));
                connection.addPacketListener(messageListener,new PacketTypeFilter(Message.class));
                connection.addPacketListener(new XmppPresenceListener(), new PacketTypeFilter(Presence.class));
                connection.addPacketInterceptor(new XmppPresenceInterceptor(), new PacketTypeFilter(Presence.class));


                // connection.addPacketListener(arg0, arg1);
                ProviderManager.getInstance().addIQProvider("muc", "MZH", new MUCPacketExtensionProvider());
                return true;
            }
        } catch (XMPPException xe) {
            xe.printStackTrace();
            connection = null;
        }catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 关闭连接
     */
    public void closeConnection() {
        if (connection != null) {
            connection.removeConnectionListener(connectionListener);
            ProviderManager.getInstance().removeIQProvider("muc", "MZH");
            try {
                connection.disconnect();
            } catch (Exception e) {
                if(Constants.IS_DEBUG)
                    Log.e("asmack dis", e.getMessage());
                e.printStackTrace();
            }
            finally{
                connection = null;
                xmppConnection = null;
            }
        }
        if(Constants.IS_DEBUG)
            Log.e("XmppConnection", "close connection");
    }

    /**
     * TODO 建立重新连接,使用程序中的USER_NAME 和PWD 直接登录
     * */
    public void reconnect(){
        new Thread(){
            @Override
            public void run() {
                try {
                    sleep(5*1000);
                    ChatActivity.isLeaving = true;
                    closeConnection();
                    login(Constants.USER_NAME, Constants.PWD);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                super.run();
            }
        }.start();
    }


    public void loadFriendAndJoinRoom(){
        new Thread(){
            public void run() {
                try {
                    getFriends();
                    sleep(1*1000);
                    if (XmppConnection.getInstance().getMyRoom()!=null) {
                        for (Room room : XmppConnection.getInstance().getMyRoom()) {
                            XmppConnection.getInstance().joinMultiUserChat(Constants.USER_NAME,room.name, false);
                        }
                    }
                    ChatActivity.isLeaving = false;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            };
        }.start();
    }

    /**
     * 登录
     *
     * @param account
     *            登录帐号
     * @param password
     *            登录密码
     * @return
     */
    public boolean login(String account, String password) {
        try {
            if (getConnection() == null)
                return false;
            //已连接, 未认证!
            if (!getConnection().isAuthenticated() && getConnection().isConnected()) {
                getConnection().login(account, password);
                // // 更改在线状态
                Presence presence = new Presence(Presence.Type.available);
                // Constants.USER_STATUS = presence.getStatus();
                presence.setMode(Presence.Mode.available);
                getConnection().sendPacket(presence);

                roster = XmppConnection.getInstance().getConnection().getRoster();
//              friendListner = new FriendListner();
//              roster.addRosterListener(friendListner);
                //监听邀请加入聊天室请求
//              MultiUserChat.addInvitationListener(getConnection(), new InvitationListener() {
//
//                  @Override
//                  public void invitationReceived(Connection arg0, String arg1, String arg2,
//                          String arg3, String arg4, Message arg5) {
//                      // TODO Auto-generated method stub
//
//                  }
//              });
                loadFriendAndJoinRoom();
                return true;
            }
        } catch (XMPPException e) {
            e.printStackTrace();
            return false;
        }
        return false;
    }

    /**
     * 注册
     *
     * @param account
     *            注册帐号
     * @param password
     *            注册密码
     * @return 1、注册成功 0、服务器没有返回结果2、这个账号已经存在3、注册失败
     */
    public IQ regist(String account, String password) {
        if (getConnection() == null)
            return null;
        Registration reg = new Registration();
        reg.setType(IQ.Type.SET);
        reg.setTo(getConnection().getServiceName());
        reg.setUsername(account);
        reg.setPassword(password);
//      reg.addAttribute("android", "geolo_createUser_android");
        PacketFilter filter = new AndFilter(new PacketIDFilter(reg.getPacketID()), new PacketTypeFilter(IQ.class));

        PacketCollector collector = getConnection().createPacketCollector(filter);
        // 给注册的Packet设置Listener,因为只有等到正真注册成功后,我们才可以交流
        // collector.addPacketListener(packetListener, filter);
        // 向服务器端,发送注册Packet包,注意其中Registration是Packet的子类
        getConnection().sendPacket(reg);
        IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
        // 停止从队列中等待
        collector.cancel();
        return result;
    }


    /**
     * 修改密码
     * @param pwd
     * @return boolean
     */
    public boolean changPwd(String pwd){
        try {
            getConnection().getAccountManager().changePassword(pwd);
            return true;
        } catch (XMPPException e) {
            e.printStackTrace();
            return false;
        }
    }

    public void setRecevier(String chatName,int chatType){
        if (getConnection() == null)
            return;

        if (chatType == ChatItem.CHAT) {
            // 创建回话
            ChatManager cm = XmppConnection.getInstance().getConnection().getChatManager();
            // 发送消息给pc服务器的好友(获取自己的服务器,和好友)
            newchat = cm.createChat(getFullUsername(chatName), null);
        }
        else if (chatType == ChatItem.GROUP_CHAT) {
            mulChat = new MultiUserChat(getConnection(), getFullRoomname(chatName));
        }
    }

    //发送文本消息
    @SuppressLint("NewApi")
    public void sendMsg(String chatName,String msg,int chatType) throws Exception{
        if (getConnection() == null){
            throw new Exception("XmppException");
        }

        if (msg.isEmpty()) {
            Tool.initToast(MyApplication.getInstance(), "随便写点什么呗");
        }
        else {
            if (chatType == ChatItem.CHAT) {
                ChatManager cm = XmppConnection.getInstance().getConnection().getChatManager();
                // 发送消息给pc服务器的好友(获取自己的服务器,和好友)
                Chat newchat = cm.createChat(getFullUsername(chatName), null);
                newchat.sendMessage(msg);
            }
            else if (chatType == ChatItem.GROUP_CHAT) {
                MultiUserChat mulChat = new MultiUserChat(getConnection(), getFullRoomname(chatName));
                mulChat.sendMessage(msg);
            }
        }
    }

    /**
     * TODO 发送消息
     * @param msg 消息内容
     * @param chatType 消息类型(聊天,还是群聊)
     * */
    @SuppressLint("NewApi")
    public void sendMsg(String msg,int chatType) throws Exception{
        if (getConnection() == null){
            throw new Exception("XmppException");
        }

        if (msg.isEmpty()) {
            Tool.initToast(MyApplication.getInstance(), "当前输入为空");
        }
        else {
            //判断是  组聊  还是单聊
            if (chatType == ChatItem.CHAT) {
                newchat.sendMessage(msg);
            }
            else if (chatType == ChatItem.GROUP_CHAT) {
                //发送群聊信息
                mulChat.sendMessage(msg);
            }
        }
    }


    //发送消息,附带参数
    public void sendMsgWithParms(String msg,String[] parms,Object[] datas,int chatType) throws Exception{
        if (getConnection() == null){
            throw new Exception("XmppException");
        }

        org.jivesoftware.smack.packet.Message message = new org.jivesoftware.smack.packet.Message();
        for (int i = 0; i < datas.length; i++) {
            message.setProperty(parms[i], datas[i]);
        }
        message.setBody(msg);

        if (chatType == ChatItem.CHAT) {
            newchat.sendMessage(message);
        }
        else if (chatType == ChatItem.GROUP_CHAT) {
            mulChat.sendMessage(msg+":::"+datas[0]);
        }
    }


    /**
     * 搜索好友
     * @param key
     * @return List<String>
     */
    public List<String> searchUser(String key){
        List<String> userList = new ArrayList<String>();
        try{
            UserSearchManager search = new UserSearchManager(getConnection());
            Form searchForm = search.getSearchForm("search."+Constants.SERVER_NAME);
            Form answerForm = searchForm.createAnswerForm();
            answerForm.setAnswer("Username", true);
            answerForm.setAnswer("search", key);
            ReportedData data = search.getSearchResults(answerForm,"search."+Constants.SERVER_NAME);

            Iterator<Row> it = data.getRows();
            Row row=null;
            while(it.hasNext()){
                row=it.next();
                userList.add(row.getValues("Username").next().toString());
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return userList;
    }


    /**
     * 添加好友 无分组
     *
     * @param userName  id
     * @return
     */
    public boolean addUser(String userName) {
        if (getConnection() == null)
            return false;
        try {
            getConnection().getRoster().createEntry(getFullUsername(userName), getFullUsername(userName), null);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * TODO 删除好友, 用户名之后添加 "@192.168.*.*"
     *
     * @param userName
     * @return
     */
    public boolean removeUser(String userName) {
        if (getConnection() == null)
            return false;
        try {
            RosterEntry entry = null;
            if (userName.contains("@"))
                entry = getConnection().getRoster().getEntry(userName);
            else
                entry = getConnection().getRoster().getEntry(userName + "@" + getConnection().getServiceName());
            if (entry == null)
                entry = getConnection().getRoster().getEntry(userName);
            getConnection().getRoster().removeEntry(entry);

            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 修改用户信息
     *
     * @param
     */
    public boolean changeVcard(VCard vcard) {
        if (getConnection() == null)
            return false;
        try {
            // 加入这句代码,解决No VCard for
            ProviderManager.getInstance().addIQProvider("vCard", "vcard-temp", new VCardProvider());
            vcard.save(getConnection());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }


    /**
     * 修改用户头像
     *
     * @param file
     */
    public Bitmap changeImage(File file) {
        Bitmap bitmap = null;
        if (getConnection() == null)
            return bitmap;
        try {
            VCard vcard = Constants.loginUser.vCard;
            // 加入这句代码,解决No VCard for
            ProviderManager.getInstance().addIQProvider("vCard", "vcard-temp", new VCardProvider());

            byte[] bytes;
            bytes = getFileBytes(file);
            String encodedImage = StringUtils.encodeBase64(bytes);
//          vcard.setAvatar(bytes, encodedImage);
            // vcard.setEncodedImage(encodedImage);
//          vcard.setField("PHOTO", "<TYPE>image/jpg</TYPE><BINVAL>" + encodedImage + "</BINVAL>", true);
            vcard.setField("avatar", encodedImage);
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
            bitmap = FormatTools.getInstance().InputStream2Bitmap(bais);
            // Image image = ImageIO.read(bais);
            //         ImageIcon ic = new ImageIcon(image); 
            vcard.save(getConnection());

        } catch (Exception e) {
            e.printStackTrace();

        }
        return bitmap;
    }

    /**
     * 获取用户信息
     * @param user
     * @return
     */
    public VCard getUserInfo(String user) {  //null 时查自己
        try {
            VCard vcard = new VCard();
            // 加入这句代码,解决No VCard for
            ProviderManager.getInstance().addIQProvider("vCard", "vcard-temp", new VCardProvider());
            if (user == null) {
                vcard.load(getConnection());
            }
            else {
                vcard.load(getConnection(), user + "@" + Constants.SERVER_NAME);
            }
            if (vcard != null)
                return vcard;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 获取用户头像信息
     *
     * @param
     * @param user
     * @return
     */
    public Bitmap getUserImage(String user) {  //null 时查自己

        ByteArrayInputStream bais = null;
        try {
            VCard vcard = new VCard();
            // 加入这句代码,解决No VCard for
            ProviderManager.getInstance().addIQProvider("vCard", "vcard-temp", new VCardProvider());
            if (user == null) {
                vcard.load(getConnection());
            }
            else {
                vcard.load(getConnection(), user + "@" + Constants.SERVER_NAME);
            }
            if (vcard == null || vcard.getAvatar() == null)
                return null;
            bais = new ByteArrayInputStream(vcard.getAvatar());

        } catch (Exception e) {
            e.printStackTrace();
        }
        if (bais == null)
            return null;
        return FormatTools.getInstance().InputStream2Bitmap(bais);
    }

    /**
     * 文件转字节
     *
     * @param file
     * @return
     * @throws IOException
     */
    private byte[] getFileBytes(File file) throws IOException {
        BufferedInputStream bis = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(file));
            int bytes = (int) file.length();
            byte[] buffer = new byte[bytes];
            int readBytes = bis.read(buffer);
            if (readBytes != buffer.length) {
                throw new IOException("Entire file not read");
            }
            return buffer;
        } finally {
            if (bis != null) {
                bis.close();
            }
        }
    }


    /**
     * 创建房间
     *
     * @param roomName
     *            房间名称
     */
    public MultiUserChat createRoom(String roomName) {//String user,
        if (getConnection() == null)
            return null;

        MultiUserChat muc = null;
        try {
            // 创建一个MultiUserChat
            muc = new MultiUserChat(getConnection(), roomName + "@conference." + getConnection().getServiceName());
            LeetCode 260 只出现一次的数字(超详细)

vbscript 各种自定义代码片段 - 有关详细信息,请参阅注释

最全最详细publiccms常用的代码片段

最全最详细publiccms其他常用代码片段(内容站点)

《Docker 源码分析》全球首发啦!

【HDFS】超详细讲解Erasure Coding-- EC架构及图解相关核心代码。