Android 实现Xmpp工具类

/**
 * XMPP服务器连接工具类.
 * 
 * @author chen.lin
 * 
 */
public class XmppManager {
    private static final String TAG = "XmppManager";
    private XMPPConnection connection;
    private static ConnectionConfiguration connectionConfig;
    private static XmppManager xmppManager;
    private Context mContext;
    private SharedPreferences sp;
    private final String CONFERENCE = "@conference.";
    //private IMConnectionListener connectionListener;

    // -----------------------------------------------------------
    private MultiUserChat muc;

    public MultiUserChat getMuc() {
        return muc;
    }

    public void setMuc(MultiUserChat muc) {
        this.muc = muc;
    }

    // -----------------------------------------------------------
    private XmppManager(Context context) {
        mContext = context;
        sp = mContext.getSharedPreferences(Constant.CONFIG, Context.MODE_PRIVATE);
        connection = init(getLoginConfig());
        //connectionListener = new IMConnectionListener();
    }

    public static XmppManager getInstance(Context context) {
        if (xmppManager == null) {
            xmppManager = new XmppManager(context);
        }
        return xmppManager;
    }

    public void saveLoginConfig(IMLoginConfig loginConfig) {
        Editor edit = sp.edit();
        edit.putString(Constant.XMPP_HOST, loginConfig.getXmppHost());
        edit.putInt(Constant.XMPP_PORT, loginConfig.getXmppPort());
        edit.putString(Constant.XMPP_SEIVICE_NAME, loginConfig.getXmppServiceName());
        edit.putString(Constant.USERNAME, loginConfig.getUsername());
        edit.putString(Constant.PASSWORD, loginConfig.getPassword());
        edit.commit();
    }

    public IMLoginConfig getLoginConfig() {
        IMLoginConfig loginConfig = new IMLoginConfig();
        loginConfig.setXmppHost(sp.getString(Constant.XMPP_HOST, Constant.VALUE_HOST_LOCAL));
        loginConfig.setXmppPort(sp.getInt(Constant.XMPP_PORT, Constant.VALUE_XMPP_PORT));
        loginConfig.setUsername(sp.getString(Constant.USERNAME, null));
        loginConfig.setPassword(sp.getString(Constant.PASSWORD, null));
        loginConfig.setXmppServiceName(sp.getString(Constant.XMPP_SEIVICE_NAME, Constant.VALUE_XMPP_SERVICE_NAME));
        return loginConfig;
    }

    // 初始化连接数据
    public XMPPConnection init(IMLoginConfig loginConfig) {
        Connection.DEBUG_ENABLED = false;
        ProviderManager pm = ProviderManager.getInstance();
        configure(pm);
        connectionConfig = new ConnectionConfiguration(loginConfig.getXmppHost(), loginConfig.getXmppPort(),
                loginConfig.getXmppServiceName());

        connectionConfig.setSASLAuthenticationEnabled(false);// 不使用SASL验证,设置为false
        connectionConfig.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
        // 允许自动连接
        connectionConfig.setReconnectionAllowed(false);
        // 允许登陆成功后更新在线状态
        connectionConfig.setSendPresence(true);
        // 收到好友邀请后manual表示需要经过同意,accept_all表示不经同意自动为好友

        Roster.setDefaultSubscriptionMode(Roster.SubscriptionMode.accept_all);
        try {
            Class.forName("org.jivesoftware.smackx.ServiceDiscoveryManager", true, XmppManager.class.getClassLoader());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        connection = new XMPPConnection(connectionConfig);
        return connection;
    }

    /**
     * 
     * 返回一个有效的xmpp连接,如果无效则返回空.
     * 
     * @return
     */
    public XMPPConnection getConnection() {
        if (connection == null) {
            throw new RuntimeException("请先初始化XMPPConnection连接");
        }
        return connection;
    }

    /**
     * 
     * 销毁xmpp连接.
     */
    public void disconnect() {
        new Thread() {
            public void run() {
                if (connection != null && connection.isConnected()) {
                    connection.disconnect();
                    connection = null;
                    /*
                     * if (connectionListener != null) {
                     * connection.removeConnectionListener(connectionListener);
                     * }
                     */
                }
            }

        }.start();
    }

    /**
     * 登陆到服务器
     * 
     * @param username
     * @param password
     * @return
     */
    public boolean login(String username, String password) {
        Roster roster;
        boolean flag = true;
        try {
            connection.login(username, password);
            // if (connectionListener != null) {
            // connection.addConnectionListener(connectionListener);
            // }
            roster = connection.getRoster();
            roster.addRosterListener(new RosterListener() {// 监听Roster
                @Override
                public void entriesAdded(Collection<String> collection) {// 添加好友的时候触发
                    String jid = "";
                    Iterator<String> it = collection.iterator();
                    if (it.hasNext()) {
                        jid = it.next() + connection.getServiceName();
                    }
                    // 订阅好友的Presence
                    Presence presence = new Presence(Presence.Type.subscribe);
                    presence.setTo(jid);
                    // presence.setMode(Presence.Mode.available);
                    connection.sendPacket(presence);
                }

                @Override
                public void entriesDeleted(Collection<String> arg0) {
                }

                @Override
                public void entriesUpdated(Collection<String> arg0) {
                }

                @Override
                public void presenceChanged(Presence p) {
                    // 当订阅的好友presence改变的时候调用
                }

            });

        } catch (Exception e) {
            flag = false;
        }
        return flag;
    }

    /**
     * 注册
     * 
     * @param account
     *            注册帐号
     * @param password
     *            注册密码
     * @return 1、注册成功 0、服务器没有返回结果2、这个账号已经存在3、注册失败
     */
    public String regist(String account, String password) {
        Log.i(TAG, "开始注册------------>");
        String str = null;
        if (connection == null)
            str = "0";
        Registration reg = new Registration();
        reg.setType(IQ.Type.SET);
        reg.setTo(connection.getServiceName());
        reg.setUsername(account);// 注意这里createAccount注册时,参数是username,不是jid,是“@”前面的部分。
        reg.setPassword(password);
        reg.addAttribute("android", "geolo_createUser_android");// 这边addAttribute不能为空,否则出错。所以做个标志是android手机创建的吧!!!!!
        PacketFilter filter = new AndFilter(new PacketIDFilter(reg.getPacketID()), new PacketTypeFilter(IQ.class));
        PacketCollector collector = connection.createPacketCollector(filter);
        connection.sendPacket(reg);
        Log.i(TAG, "注册结束------------>");
        IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
        collector.cancel();// 停止请求results(是否成功的结果)
        if (result == null) {
            Log.e(TAG, "无响应.");
            str = "0";
        } else if (result.getType() == IQ.Type.ERROR) {
            if (result.getError().toString().equalsIgnoreCase("conflict(409)")) {
                Log.e(TAG, "这个账号已经存在");
                str = "2";
            } else {
                Log.e(TAG, "注册失败");
                str = "3";
            }
        } else if (result.getType() == IQ.Type.RESULT) {
            Log.e(TAG, "恭喜你注册成功");
            str = "1";
        }

        return str;
    }

    /**
     * 用户加入时向服务器发送的报文 ,就是XMPPCONNECTION来发送
     * 
     * @用法:connnection.sendPacket(leaveXml());
     * @return
     */
    public IQ joinXml(String jid) {
        IQ iq = new IQ() {
            public String getChildElementXML() {
                StringBuilder buf = new StringBuilder();
                buf.append("<query xmlns=\"jabber:iq:private\">");
                buf.append("<storage xmlns=\"storage:bookmarks\">");
                buf.append("<").append("conference").append(" name=\"ccc\"").append(" autojoin=\"false\"").append("");
                buf.append("</storage>");
                buf.append("</query>");
                return buf.toString();
            }
        };
        iq.setType(IQ.Type.SET);
        // 方法如名,这里是设置这份报文来至那个JID,后边的/smack是这段信息来至哪个端,如spark端就是/spark,android就是/Smack
        iq.setFrom(jid + "/Smack");
        return iq;
    }

    /**
     * 获取用户的vcard信息 .
     * 
     * @return
     * 
     */
    public VCard getUserVCard(String jid) {
        VCard vcard = new VCard();
        try {
            if (connection.isConnected() && connection.isAuthenticated()) {
                vcard.load(connection, jid);
            }
        } catch (XMPPException e) {
            e.printStackTrace();
        }
        return vcard;
    }

    /**
     * 
     * 保存用户的vcard信息. 注:修改vcard时,头像会丢失,此处为asmack.jar的bug,目前还无法修复
     * 
     * @param vCard
     * @return
     * 
     */
    public VCard saveUserVCard(VCard vCard) {
        try {
            vCard.save(connection);
            return getUserVCard(vCard.getJabberId());
        } catch (XMPPException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 
     * 获取用户头像信息 .
     * 
     * @param connection
     * @param jid
     * @return
     */
    public InputStream getUserImage(String jid) {
        InputStream ic = null;
        try {
            VCard vcard = new VCard();
            vcard.load(connection, jid);

            if (vcard == null || vcard.getAvatar() == null) {
                return null;
            }
            ByteArrayInputStream bais = new ByteArrayInputStream(vcard.getAvatar());
            return bais;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ic;
    }

    /**
     * 从服务器上查询用户
     * 
     * @param username
     * @param connection
     * @return
     */
    public List<IMUser> findUsers(String username) {
        List<IMUser> results = new ArrayList<IMUser>();
        try {
            UserSearchManager usm = new UserSearchManager(connection);
            String serverDomain = "search." + connection.getServiceName();
            Form searchForm = usm.getSearchForm(serverDomain);
            Form answerForm = searchForm.createAnswerForm();
            answerForm.setAnswer("Username", true);
            answerForm.setAnswer("search", username);
            ReportedData data = usm.getSearchResults(answerForm, serverDomain);
            Iterator<Row> it = data.getRows();
            Row row = null;
            IMUser user = null;
            while (it.hasNext()) {
                user = new IMUser();
                row = it.next();
                String jid = row.getValues("Jid").next().toString();
                String name = row.getValues("Username").next().toString();
                String email = row.getValues("Email").next().toString();
                user.setJID(jid);
                user.setName(name);
                user.setEmail(email);
                results.add(user);
            }
            return results;
        } catch (XMPPException e) {
            e.printStackTrace();
        }
        return results;
    }

    /**
     * 查找用户
     * 
     * @param serverDomain
     * @param userName
     * @return
     */
    public List<IMUser> searchUsers(String serverDomain, String userName) {
        List<IMUser> list = new ArrayList<IMUser>();
        UserSearchManager userSearchManager = new UserSearchManager(connection);
        try {
            Form searchForm = userSearchManager.getSearchForm("search." + serverDomain);
            Form answerForm = searchForm.createAnswerForm();
            answerForm.setAnswer("Username", true);
            answerForm.setAnswer("Name", true);
            answerForm.setAnswer("search", userName);
            ReportedData data = userSearchManager.getSearchResults(answerForm, "search." + serverDomain);
            Iterator<Row> rows = data.getRows();
            while (rows.hasNext()) {
                IMUser user = new IMUser();
                Row row = rows.next();
                user.setName(row.getValues("Username").next().toString());
                user.setNickName(row.getValues("Name").next().toString());
                Logger.i(TAG, user.toString());
                list.add(user);
            }
        } catch (XMPPException e) {
            Logger.i(TAG, Log.getStackTraceString(e));
        }
        return list;
    }

    /**
     * 发送文件
     * 
     * @param recvUser
     * @param filePath
     */
    public void sendFile(String recvUser, String filePath) {
        FileTransferManager fileTransferManager = new FileTransferManager(connection);
        try {
            final OutgoingFileTransfer outgoingFileTransfer = fileTransferManager.createOutgoingFileTransfer(recvUser);
            outgoingFileTransfer.sendFile(new File(filePath), "outgoingFileTransfer ^_^");
            new App().execRunnable(new Runnable() {
                @Override
                public void run() {
                    while (!outgoingFileTransfer.isDone()) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                        }
                    }
                    if (outgoingFileTransfer.getStatus().equals(Status.complete))
                        Logger.i(TAG, "上送完毕");
                    else if (outgoingFileTransfer.getStatus().equals(Status.error))
                        Logger.i(TAG, "上送出错");
                }
            });
        } catch (XMPPException e) {
            Logger.i(TAG, "上送文件异常");
            Logger.i(TAG, Log.getStackTraceString(e));
        }
    }

    /**
     * 注册文件接收器
     */
    public void registRecvFileListener() {
        FileTransferManager fileTransferManager = new FileTransferManager(connection);
        fileTransferManager.addFileTransferListener(new FileTransferListener() {
            public void fileTransferRequest(final FileTransferRequest request) {
                final IncomingFileTransfer transfer = request.accept();
                try {
                    Logger.i(TAG, "接受文件:" + transfer.getFileName());
                    transfer.recieveFile(new File(Environment.getExternalStorageDirectory() + "/"
                            + request.getFileName()));
                    new App().execRunnable(new Runnable() {
                        @Override
                        public void run() {
                            while (!transfer.isDone()) {
                                Logger.i(TAG, "进度:" + transfer.getProgress());
                                try {
                                    Thread.sleep(100);
                                } catch (InterruptedException e) {
                                    Logger.i(TAG, Log.getStackTraceString(e));
                                }
                            }
                            Logger.i(TAG, "接受状态" + transfer.getStatus());
                            if (transfer.getStatus().equals(Status.complete))
                                Logger.i(TAG, "接受完毕");
                            else if (transfer.getStatus().equals(Status.error)) {
                                transfer.cancel();
                                Logger.i(TAG, "接受出错");
                            }
                        }
                    });
                } catch (Exception e) {
                    Logger.i(TAG, Log.getStackTraceString(e));
                    Logger.i(TAG, "文件接收出错");
                    transfer.cancel();
                }
            }
        });
    }

    /**
     * 返回群组所有组信息 <RosterGroup>  
     * 
     * @return List(RosterGroup)   
     */
    public List<RosterGroup> getGroups(Roster roster) {
        List<RosterGroup> groupsList = new ArrayList<RosterGroup>();
        Collection<RosterGroup> rosterGroup = roster.getGroups();
        Iterator<RosterGroup> i = rosterGroup.iterator();
        while (i.hasNext()) {
            groupsList.add(i.next());
        }
        return groupsList;
    }

    /**
     * 创建群组
     * 
     * @param roster
     * @param groupName
     * @return
     */
    public boolean createGroup(Roster roster, String groupName) {
        RosterEntry entry = roster.getEntries().iterator().next();
        try {
            roster.createGroup(groupName).addEntry(entry);
            return true;
        } catch (XMPPException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 返回相应(groupName)组里的所有用户<RosterEntry>
     * 
     * @return List(RosterEntry)
     */
    public List<RosterEntry> getEntriesByGroup(Roster roster, String groupName) {
        List<RosterEntry> EntriesList = new ArrayList<RosterEntry>();
        RosterGroup rosterGroup = roster.getGroup(groupName);
        Collection<RosterEntry> rosterEntry = rosterGroup.getEntries();
        Iterator<RosterEntry> it = rosterEntry.iterator();

        while (it.hasNext())
            EntriesList.add(it.next());
        return EntriesList;
    }

    /**
     * 获得某个群组中的所有成员
     * 
     * @param roster
     * @param groupName
     * @return
     */
    public List<RosterEntry> getEntrysByGroup(Roster roster, String groupName) {
        List<RosterEntry> list = new ArrayList<RosterEntry>();
        RosterGroup group = roster.getGroup(groupName);
        list.addAll(group.getEntries());
        return list;
    }

    /**
     * 返回所有用户信息 <RosterEntry>
     * 
     * @return List(RosterEntry)
     */
    public List<RosterEntry> getAllEntries(Roster roster) {
        List<RosterEntry> EntriesList = new ArrayList<RosterEntry>();
        Collection<RosterEntry> rosterEntry = roster.getEntries();
        Iterator<RosterEntry> i = rosterEntry.iterator();
        while (i.hasNext())
            EntriesList.add(i.next());
        return EntriesList;
    }

    /**
     * 获得所有的好友
     * 
     * @param roster
     * @return
     */
    public List<RosterEntry> getAllEntrys(Roster roster) {
        List<RosterEntry> list = new ArrayList<RosterEntry>();
        list.addAll(roster.getEntries());
        return list;
    }

    /**
     * 添加一个组
     */
    public boolean addGroup(Roster roster, String groupName) {
        try {
            roster.createGroup(groupName);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除一个组
     */
    public boolean removeGroup(Roster roster, String groupName) {
        // roster.removeEntry(groupName);
        return false;
    }

    /**
     * 添加一个好友 无分组
     */
    public boolean addUser(Roster roster, String userName, String nickName) {
        try {
            roster.createEntry(userName, nickName, null);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 添加好友
     * 
     * @param roster
     * @param userName
     * @param name
     * @param groupName
     *            是否有分组
     * @return
     */
    public boolean addUser(Roster roster, String userName, String name, String groupName) {
        try {
            roster.createEntry(userName, name, null == groupName ? null : new String[] { groupName });
            return true;
        } catch (XMPPException e) {
            Log.e(TAG, Log.getStackTraceString(e));
        }
        return false;
    }

    /**
     * 删除一个好友
     * 
     * @param roster
     * @param userName
     * @return
     */
    public boolean removeUser(Roster roster, String userName) {
        try {
            if (userName.contains("@"))
                userName = userName.split("@")[0];
            RosterEntry entry = roster.getEntry(userName);
            if (null != entry)
                roster.removeEntry(entry);
            return true;
        } catch (XMPPException e) {
            Log.e(TAG, Log.getStackTraceString(e));
        }
        return false;
    }

    /**
     * 添加用户到群组
     * 
     * @param roster
     * @param userName
     * @param groupName
     */
    public void addUserToGroup(Roster roster, String userName, String groupName) {
        RosterGroup group = roster.getGroup(groupName);
        if (null == group) {
            group = roster.createGroup(groupName);
        }
        RosterEntry entry = roster.getEntry(userName);
        try {
            group.addEntry(entry);
        } catch (XMPPException e) {
            Log.e(TAG, Log.getStackTraceString(e));
        }
    }

    /**
     * 修改心情
     * 
     * @param connection
     * @param status
     */
    public void changeStateMessage(String status) {
        Presence presence = new Presence(Presence.Type.available);
        presence.setStatus(status);
        connection.sendPacket(presence);
    }

    /**
     * 更改用户头像
     * 
     * @param file
     * @param jid
     * @throws XMPPException
     * @throws IOException
     */
    public void changeImage(File file, String jid) throws XMPPException, IOException {
        VCard vcard = new VCard();
        vcard.load(connection, jid);
        byte[] bytes;
        bytes = getFileBytes(file);
        String encodedImage = StringUtils.encodeBase64(bytes);
        vcard.setAvatar(bytes, encodedImage);
        vcard.setEncodedImage(encodedImage);
        vcard.save(connection);
    }

    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 pm
     */
    public MultiUserChat createRoom(String roomName, String roomPwd, String subject) {
        if (getConnection() == null)
            return null;
        // 使用XMPPConnection创建一个MultiUserChat
        MultiUserChat multiUserChat = new MultiUserChat(connection, roomName + CONFERENCE + connection.getServiceName());
        try {
            // 创建聊天室
            multiUserChat.create(roomName);
            // 获得聊天室的配置表单
            Form configForm = multiUserChat.getConfigurationForm();
            // 根据原始表单创建一个要提交的新表单。
            Form submitForm = configForm.createAnswerForm();
            // 向要提交的表单添加默认答复
            for (Iterator<FormField> fields = configForm.getFields(); fields.hasNext();) {
                FormField formField = fields.next();
                if (!formField.getType().equals(FormField.TYPE_HIDDEN) && formField.getVariable() != null) {
                    // 设置默认值作为答复
                    submitForm.setDefaultAnswer(formField.getVariable());
                }
            }
            List<String> owners = new ArrayList<String>();
            owners.add(connection.getUser());

            // 设置聊天室的新拥有者
            // List owners = new ArrayList();
            // owners.add("liaonaibo2\\40slook.cc");
            // owners.add("liaonaibo1\\40slook.cc");
            // submitForm.setAnswer("muc#roomconfig_roomowners", owners);

            submitForm.setAnswer("muc#roomconfig_passwordprotectedroom", true);
            // 设置聊天室是持久聊天室,即将要被保存下来
            submitForm.setAnswer("muc#roomconfig_persistentroom", true);
            // 房间仅对成员开放
            submitForm.setAnswer("muc#roomconfig_membersonly", false);
            // 允许占有者邀请其他人
            submitForm.setAnswer("muc#roomconfig_allowinvites", true);
            // 能够发现占有者真实 JID 的角色
            // submitForm.setAnswer("muc#roomconfig_whois", "anyone");
            submitForm.setAnswer("muc#roomconfig_maxusers", Arrays.asList("500"));
            // 登录房间对话
            submitForm.setAnswer("muc#roomconfig_enablelogging", true);
            // 仅允许注册的昵称登录
            submitForm.setAnswer("x-muc#roomconfig_reservednick", true);
            // 允许使用者修改昵称
            submitForm.setAnswer("x-muc#roomconfig_canchangenick", true);
            // 允许用户注册房间
            submitForm.setAnswer("x-muc#roomconfig_registration", true);
            submitForm.setAnswer("muc#roomconfig_roomsecret", roomPwd);
            submitForm.setAnswer("muc#roomconfig_roomdesc", subject);
            // 发送已完成的表单(有默认值)到服务器来配置聊天室
            multiUserChat.sendConfigurationForm(submitForm);

            // 通知主界面已创建了新的房间, 主界面需要刷新显示
            Uri uri = Uri.parse(Constant.IM_ROOM_CONTENT_PATH);
            mContext.getContentResolver().notifyChange(uri, null);

        } catch (XMPPException e) {
            e.getStackTrace();
            return null;
        }
        return multiUserChat;
    }

    /**
     * 初始化房间列表
     */
    public void initChatRoom(String jid) {
        List<DiscoverItems.Item> listDiscoverItems = new ArrayList<DiscoverItems.Item>();
        // 获得与XMPPConnection相关的ServiceDiscoveryManager
        ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);

        // 获得指定XMPP实体的项目
        // 这个例子获得与在线目录服务相关的项目
        DiscoverItems discoItems;
        try {
            discoItems = discoManager.discoverItems(jid);
            // 获得被查询的XMPP实体的要查看的项目
            @SuppressWarnings("rawtypes")
            Iterator it = discoItems.getItems();
            // 显示远端XMPP实体的项目
            while (it.hasNext()) {
                DiscoverItems.Item item = (DiscoverItems.Item) it.next();
                listDiscoverItems.add(item);
            }
        } catch (XMPPException e) {
            e.printStackTrace();
        }
    }

    /**
     * 加入聊天室
     * 
     * @param user
     * @param pwd
     *            会议室密码
     * @param roomName
     * @return
     */
    public MultiUserChat joinRoom(String user, String pwd, String roomName) {
        MultiUserChat muc = new MultiUserChat(connection, roomName.contains(CONFERENCE) ? roomName : roomName
                + CONFERENCE + connection.getServiceName());
        DiscussionHistory history = new DiscussionHistory();
        history.setMaxStanzas(100);
        // history.setSince(new Date(2014, 01, 01));
        // history.setSince(new Date());
        try {
            muc.join(user, pwd, history, SmackConfiguration.getPacketReplyTimeout());
        } catch (XMPPException e) {
            e.printStackTrace();
            return null;
        }
        return muc;
    }

    /**
     * 查询会议室成员名字
     * 
     * @param muc
     */
    public List<String> findMulitUser(MultiUserChat muc) {
        if (getConnection() == null)
            return null;
        List<String> listUser = new ArrayList<String>();
        Iterator<String> it = muc.getOccupants();
        // 遍历出聊天室人员名称
        while (it.hasNext()) {
            // 聊天室成员名字
            String name = StringUtils.parseResource(it.next());
            listUser.add(name);
        }
        return listUser;
    }

    /**
     * 获得有参加人数的聊天室
     * 
     * @return
     */
    public List<IMMucRoom> getJoinedRooms() {
        List<IMMucRoom> rooms = new ArrayList<IMMucRoom>();
        Iterator<String> it = MultiUserChat.getJoinedRooms(connection, connection.getUser());
        while (it.hasNext()) {
            IMMucRoom room = new IMMucRoom();
            room.name = it.next();
            rooms.add(room);
        }
        return rooms;
    }

    /**
     * 创建私聊
     * 
     * @param participant
     * @param listener
     * @return
     */
    public Chat createPrivateChat(String participant, MessageListener listener) {
        return muc.createPrivateChat(participant, listener);
    }

    /**
     * 离开聊天室
     */
    public void leaveRoom() {
        if (null != muc)
            muc.leave();
        muc = null;
    }

    /**
     * 获取服务器上所有会议室
     * 
     * @return
     * @throws XMPPException
     */
    public List<IMMucRoom> getAllRooms() throws XMPPException {
        List<IMMucRoom> list = new ArrayList<IMMucRoom>();
        new ServiceDiscoveryManager(connection);
        if (!MultiUserChat.getHostedRooms(connection, connection.getServiceName()).isEmpty()) {

            Collection<HostedRoom> rooms = MultiUserChat.getHostedRooms(connection,
                    "conference." + connection.getServiceName());// 获取服务器上面存在的所有聊天室
            // 查询服务器上的聊天室
            // Collection<HostedRoom> rooms =
            // MultiUserChat.getHostedRooms(connection,
            // connection.getServiceName());
            for (HostedRoom room : rooms) {
                // 查看Room消息
                IMMucRoom friendrooms = new IMMucRoom();
                friendrooms.setName(room.getName());// 聊天室的名称
                friendrooms.setJid(room.getJid());// 聊天室JID

                RoomInfo roomInfo = MultiUserChat.getRoomInfo(connection, room.getJid());
                if (roomInfo != null) {
                    friendrooms.setOccupants(roomInfo.getOccupantsCount());// 聊天室中占有者数量
                    friendrooms.setDescription(roomInfo.getDescription());// 聊天室的描述
                    friendrooms.setSubject(roomInfo.getSubject());// 聊天室的主题
                }
                list.add(friendrooms);
            }
        }
        return list;
    }

    /**
     * 初始化会议室列表
     */
    public List<HostedRoom> getHostRooms() {
        if (getConnection() == null)
            return null;
        Collection<HostedRoom> hostrooms = null;
        List<HostedRoom> roominfos = new ArrayList<HostedRoom>();
        try {
            new ServiceDiscoveryManager(getConnection());
            hostrooms = MultiUserChat.getHostedRooms(getConnection(), getConnection().getServiceName());
            for (HostedRoom entry : hostrooms) {
                roominfos.add(entry);
                Logger.i("room", "名字:" + entry.getName() + " - ID:" + entry.getJid());
            }
            Logger.i("room", "服务会议数量:" + roominfos.size());
        } catch (XMPPException e) {
            e.printStackTrace();
        }
        return roominfos;
    }

    /**
     * 用户是否支持的聊天室
     * 
     * @param user
     * @return
     */
    public boolean isUserSupportMUC(String user) {
        return MultiUserChat.isServiceEnabled(connection, user);
    }

    /**
     * 得到所有离线消息
     * 
     * @return
     */
    public List<Message> getOffLineMessages() {
        List<Message> msgs = new ArrayList<Message>();
        OfflineMessageManager offLineMessageManager = new OfflineMessageManager(connection);
        try {
            Iterator<Message> it = offLineMessageManager.getMessages();
            while (it.hasNext()) {
                Message msg = it.next();
                msgs.add(msg);
            }
            offLineMessageManager.deleteMessages();
        } catch (XMPPException e) {
            e.printStackTrace();
        }
        return msgs;
    }

    /**
     * 获取离线消息
     * 
     * @return
     */
    public Map<String, List<HashMap<String, String>>> getHisMessage() {
        if (getConnection() == null)
            return null;
        Map<String, List<HashMap<String, String>>> offlineMsgs = null;
        try {
            OfflineMessageManager offlineManager = new OfflineMessageManager(getConnection());
            Iterator<Message> it = offlineManager.getMessages();

            int count = offlineManager.getMessageCount();
            if (count <= 0)
                return null;
            offlineMsgs = new HashMap<String, List<HashMap<String, String>>>();

            while (it.hasNext()) {
                Message message = it.next();
                String fromUser = StringUtils.parseName(message.getFrom());
                HashMap<String, String> histrory = new HashMap<String, String>();
                histrory.put("useraccount", StringUtils.parseName(getConnection().getUser()));
                histrory.put("friendaccount", fromUser);
                histrory.put("info", message.getBody());
                histrory.put("type", "left");
                if (offlineMsgs.containsKey(fromUser)) {
                    offlineMsgs.get(fromUser).add(histrory);
                } else {
                    List<HashMap<String, String>> temp = new ArrayList<HashMap<String, String>>();
                    temp.add(histrory);
                    offlineMsgs.put(fromUser, temp);
                }
            }
            offlineManager.deleteMessages();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return offlineMsgs;
    }

    /**
     * 判断OpenFire用户的状态 strUrl : url格式 -
     * http://my.openfire.com:9090/plugins/presence
     * /status?jid=user1@SERVER_NAME&type=xml 返回值 : 0 - 用户不存在; 1 - 用户在线; 2 -
     * 用户离线 说明 :必须要求 OpenFire加载 presence 插件,同时设置任何人都可以访问
     */
    public int IsUserOnLine(String user, String host) {
        String url = "http://" + host + ":9090/plugins/presence/status?" + "jid=" + user + "@"
                + connection.getServiceName() + "&type=xml";
        int shOnLineState = 0; // 不存在
        try {
            URL oUrl = new URL(url);
            URLConnection oConn = oUrl.openConnection();
            if (oConn != null) {
                BufferedReader oIn = new BufferedReader(new InputStreamReader(oConn.getInputStream()));
                if (null != oIn) {
                    String strFlag = oIn.readLine();
                    oIn.close();
                    if (strFlag.indexOf("type=\"unavailable\"") >= 0) {
                        shOnLineState = 2;
                    }
                    if (strFlag.indexOf("type=\"error\"") >= 0) {
                        shOnLineState = 0;
                    } else if (strFlag.indexOf("priority") >= 0 || strFlag.indexOf("id=\"") >= 0) {
                        shOnLineState = 1;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return shOnLineState;
    }

    /**
     * 设置状态 表示XMPP状态的packet。每个presence packet都有一个状态。 用枚举类型Presence.Type的值表示:
     * 
     * @available -- (默认)用户空闲状态
     * @unavailable -- 用户没空看消息
     * @subscribe -- 请求订阅别人,即请求加对方为好友
     * @subscribed -- 统一被别人订阅,也就是确认被对方加为好友
     * @unsubscribe -- 他取消订阅别人,请求删除某好友
     * @subscribed -- 拒绝被别人订阅,即拒绝对放的添加请求
     * @error -- 当前状态packet有错误
     * @param state
     */
    public void setPresence(int state) {
        Presence presence;
        switch (state) {
        case 0:
            presence = new Presence(Presence.Type.available);// (默认)用户空闲状态
            connection.sendPacket(presence);
            Log.e(TAG, "设置在线");
            break;
        case 1:
            presence = new Presence(Presence.Type.available);
            presence.setMode(Presence.Mode.chat);// /presence.setMode(Presence.Mode.dnd);
            connection.sendPacket(presence);
            Log.e(TAG, "Q我吧");
            Log.e(TAG, presence.toXML());
            break;
        case 2:
            presence = new Presence(Presence.Type.available);
            presence.setMode(Presence.Mode.dnd);
            connection.sendPacket(presence);
            Log.e(TAG, "忙碌");
            Log.e(TAG, presence.toXML());
            break;
        case 3:
            presence = new Presence(Presence.Type.available);
            presence.setMode(Presence.Mode.away);
            connection.sendPacket(presence);
            Log.e(TAG, "离开");
            Log.e(TAG, presence.toXML());
            break;
        case 4:
            Roster roster = connection.getRoster();
            Collection<RosterEntry> entries = roster.getEntries();
            for (RosterEntry entity : entries) {
                presence = new Presence(Presence.Type.unavailable);// 用户没空看消息
                presence.setPacketID(Packet.ID_NOT_AVAILABLE);
                presence.setFrom(connection.getUser());
                presence.setTo(entity.getUser());
                connection.sendPacket(presence);
                Log.e(TAG, presence.toXML());
            }
            Log.e(TAG, "告知其他用户-隐身");
            // 向同一用户的其他客户端发送隐身状态
            presence = new Presence(Presence.Type.unavailable);
            presence.setPacketID(Packet.ID_NOT_AVAILABLE);
            presence.setFrom(connection.getUser());
            presence.setTo(StringUtils.parseBareAddress(connection.getUser()));
            connection.sendPacket(presence);
            Log.e(TAG, "告知本用户的其他客户端-隐身");
            Log.e(TAG, presence.toXML());
            break;
        case 5:
            presence = new Presence(Presence.Type.unavailable);
            connection.sendPacket(presence);
            Log.e(TAG, "离线");
            Log.e(TAG, presence.toXML());
            break;
        default:
            break;
        }
    }

    /**
     * 删除账号
     * 
     * @return
     */
    public boolean deleteCount() {
        try {
            connection.getAccountManager().deleteAccount();
            return true;
        } catch (XMPPException e) {
            Log.e(TAG, Log.getStackTraceString(e));
        }
        return false;
    }

    /**
     * 开启服务
     */
    public void startService() {
        // 好友联系人服务
        Intent server = new Intent(mContext, IMContactService.class);
        mContext.startService(server);
        // 聊天服务
        Intent chatServer = new Intent(mContext, IMChatService.class);
        mContext.startService(chatServer);

        // 自动恢复连接服务
        Intent reConnectService = new Intent(mContext, IMReConnectService.class);
        mContext.startService(reConnectService);

        // 系统消息连接服务
        Intent imSystemMsgService = new Intent(mContext, IMSystemMsgService.class);
        mContext.startService(imSystemMsgService);
    }

    /**
     * 
     * 销毁服务.
     */
    public void stopService() {
        // 好友联系人服务
        Intent server = new Intent(mContext, IMContactService.class);
        boolean isRunning = ServiceUtils.isServiceRunning(mContext, "com.ymerp.android.service.IMContactService");
        if (isRunning) {
            mContext.stopService(server);
        }

        // 聊天服务
        Intent chatServer = new Intent(mContext, IMChatService.class);
        isRunning = ServiceUtils.isServiceRunning(mContext, "com.ymerp.android.service.IMChatService");
        if (isRunning) {
            mContext.stopService(chatServer);
        }

        // 自动恢复连接服务
        Intent reConnectService = new Intent(mContext, IMReConnectService.class);
        isRunning = ServiceUtils.isServiceRunning(mContext, "com.ymerp.android.service.IMReConnectService");
        if (isRunning) {
            mContext.stopService(reConnectService);
        }

        // 系统消息连接服务
        Intent imSystemMsgService = new Intent(mContext, IMSystemMsgService.class);
        isRunning = ServiceUtils.isServiceRunning(mContext, "com.ymerp.android.service.IMSystemMsgService");
        if (isRunning) {
            mContext.stopService(imSystemMsgService);
        }
    }

    /**
     * 
     * 处理离线消息.
     * 
     * @param connection
     */
    public void dealOfflineMsg() {
        OfflineMessageManager offlineManager = new OfflineMessageManager(connection);
        try {
            Iterator<org.jivesoftware.smack.packet.Message> it = offlineManager.getMessages();
            Logger.i("离线消息数量: ", "" + offlineManager.getMessageCount());
            while (it.hasNext()) {
                org.jivesoftware.smack.packet.Message message = it.next();
                Logger.i("收到离线消息", "Received from 【" + message.getFrom() + "】 message: " + message.getBody());
                if (message != null && message.getBody() != null && !message.getBody().equals("null")) {
                    IMMessage msg = new IMMessage();
                    String time = (String) message.getProperty(IMMessage.KEY_TIME);
                    msg.setTime(time == null ? DateUtil.getCurDateStr() : time);
                    msg.setContent(message.getBody());
                    if (Message.Type.error == message.getType()) {
                        msg.setType(IMMessage.ERROR);
                    } else {
                        msg.setType(IMMessage.SUCCESS);
                    }
                    String from = message.getFrom().split("/")[0];
                    msg.setFromSubJid(from);

                    // 生成通知
                    IMNoticeManager noticeManager = IMNoticeManager.getInstance(mContext);
                    IMNotice notice = new IMNotice();
                    notice.setTitle("会话信息");
                    notice.setNoticeType(IMNotice.CHAT_MSG);
                    notice.setContent(message.getBody());
                    notice.setFrom(from);
                    notice.setStatus(IMNotice.UNREAD);
                    notice.setNoticeTime(time == null ? DateUtil.getCurDateStr() : time);

                    // 历史记录
                    IMMessage newMessage = new IMMessage();
                    newMessage.setMsgType(0);
                    newMessage.setFromSubJid(from);
                    newMessage.setContent(message.getBody());
                    newMessage.setTime(time == null ? DateUtil.getCurDateStr() : time);
                    IMMessageManager.getInstance(mContext).saveIMMessage(newMessage);

                    long noticeId = noticeManager.saveNotice(notice);
                    if (noticeId != -1) {
                        Intent intent = new Intent(Constant.NEW_MESSAGE_ACTION);
                        intent.putExtra(IMMessage.IMMESSAGE_KEY, msg);
                        intent.putExtra("noticeId", noticeId);
                        mContext.sendBroadcast(intent);
                        IMUtils.setNotiType(mContext, R.drawable.im_head,
                                mContext.getResources().getString(R.string.new_message), notice.getContent(),
                                IMChatActivity.class, from);
                    }
                }
            }

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

    }

    /**
     * 连接监听类
     * 
     */
    class IMConnectionListener implements ConnectionListener {
        private Timer timer;
        private String username;
        private String password;
        private int logintime = 2000;

        @Override
        public void connectionClosed() {
            Log.i(TAG, "连接关闭");
            // 关闭连接
            disconnect();
            // 重连服务器
            timer = new Timer();
            timer.schedule(new timetask(), logintime);
        }

        @Override
        public void connectionClosedOnError(Exception e) {
            Log.i(TAG, "连接关闭异常");
            // 判斷為帳號已被登錄
            boolean error = e.getMessage().equals("stream:error (conflict)");
            if (!error) {
                // 关闭连接
                disconnect();
                // 重连服务器
                timer = new Timer();
                timer.schedule(new timetask(), logintime);
            }
        }

        class timetask extends TimerTask {
            @Override
            public void run() {
                username = sp.getString(Constant.USERNAME, null);
                password = sp.getString(Constant.PASSWORD, null);
                if (username != null && password != null) {
                    Logger.i(TAG, "尝试登陆");
                    // 连接服务器
                    if (login(username, password)) {
                        Logger.i(TAG, "登陆成功");
                    } else {
                        Logger.i(TAG, "重新登陆");
                        timer.schedule(new timetask(), logintime);
                    }
                }
            }
        }

        @Override
        public void reconnectingIn(int arg0) {
        }

        @Override
        public void reconnectionFailed(Exception arg0) {
        }

        @Override
        public void reconnectionSuccessful() {
        }

    }

    public void configure(ProviderManager pm) {
        // Private Data Storage
        pm.addIQProvider("query", "jabber:iq:private", new PrivateDataManager.PrivateDataIQProvider());
        // Time
        try {
            pm.addIQProvider("query", "jabber:iq:time", Class.forName("org.jivesoftware.smackx.packet.Time"));
        } catch (ClassNotFoundException e) {
        }
        // XHTML
        pm.addExtensionProvider("html", "http://jabber.org/protocol/xhtml-im", new XHTMLExtensionProvider());
        // Roster Exchange
        pm.addExtensionProvider("x", "jabber:x:roster", new RosterExchangeProvider());
        // Message Events
        pm.addExtensionProvider("x", "jabber:x:event", new MessageEventProvider());
        // Chat State
        pm.addExtensionProvider("active", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
        pm.addExtensionProvider("composing", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
        pm.addExtensionProvider("paused", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
        pm.addExtensionProvider("inactive", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
        pm.addExtensionProvider("gone", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
        // FileTransfer
        pm.addIQProvider("si", "http://jabber.org/protocol/si", new StreamInitiationProvider());
        // Group Chat Invitations
        pm.addExtensionProvider("x", "jabber:x:conference", new GroupChatInvitation.Provider());
        // Service Discovery # Items
        pm.addIQProvider("query", "http://jabber.org/protocol/disco#items", new DiscoverItemsProvider());
        // Service Discovery # Info
        pm.addIQProvider("query", "http://jabber.org/protocol/disco#info", new DiscoverInfoProvider());
        // Data Forms
        pm.addExtensionProvider("x", "jabber:x:data", new DataFormProvider());
        // MUC User
        pm.addExtensionProvider("x", "http://jabber.org/protocol/muc#user", new MUCUserProvider());
        // MUC Admin
        pm.addIQProvider("query", "http://jabber.org/protocol/muc#admin", new MUCAdminProvider());
        // MUC Owner
        pm.addIQProvider("query", "http://jabber.org/protocol/muc#owner", new MUCOwnerProvider());
        // Delayed Delivery
        pm.addExtensionProvider("x", "jabber:x:delay", new DelayInformationProvider());
        // Version
        try {
            pm.addIQProvider("query", "jabber:iq:version", Class.forName("org.jivesoftware.smackx.packet.Version"));
        } catch (ClassNotFoundException e) {
        }
        // VCard
        pm.addIQProvider("vCard", "vcard-temp", new VCardProvider());
        // Offline Message Requests
        pm.addIQProvider("offline", "http://jabber.org/protocol/offline", new OfflineMessageRequest.Provider());
        // Offline Message Indicator
        pm.addExtensionProvider("offline", "http://jabber.org/protocol/offline", new OfflineMessageInfo.Provider());
        // Last Activity
        pm.addIQProvider("query", "jabber:iq:last", new LastActivity.Provider());
        // User Search
        pm.addIQProvider("query", "jabber:iq:search", new UserSearch.Provider());
        // SharedGroupsInfo
        pm.addIQProvider("sharedgroup", "http://www.jivesoftware.org/protocol/sharedgroup",
                new SharedGroupsInfo.Provider());
        // JEP-33: Extended Stanza Addressing
        pm.addExtensionProvider("addresses", "http://jabber.org/protocol/address", new MultipleAddressesProvider());
    }

}

———————————————————————
有需求者请加qq:136137465,非诚勿扰
(java 架构师全套教程,共760G, 让你从零到架构师,每月轻松拿3万)
01.高级架构师四十二个阶段高
02.Java高级系统培训架构课程148课时
03.Java高级互联网架构师课程
04.Java互联网架构Netty、Nio、Mina等-视频教程
05.Java高级架构设计2016整理-视频教程
06.架构师基础、高级片
07.Java架构师必修linux运维系列课程
08.Java高级系统培训架构课程116课时
(送:hadoop系列教程,java设计模式与数据结构, Spring Cloud微服务, SpringBoot入门)
——————————————————————–

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lovoo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值