xmpp openfire smack android IM demo

本文介绍了一种基于 Smack 库实现 XMPP 协议的即时通讯应用开发方案,包括用户注册、登录、好友管理、文件传输等功能,并详细展示了聊天室的创建、加入和聊天流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先推荐几个链接

1、http://www.igniterealtime.org/builds/smack/docs/latest/documentation/ 里面很多demo code

2、http://www.igniterealtime.org/builds/smack/docs/3.4.0/javadoc/overview-summary.html API


准备工作:

1、首先你要安装Openfire,方便调试、验证,具体配置可以百度、google,提供一个参考,请猛戳

2、安装Spark,这是一个客户端,可以协助测试,推荐安装,http://www.igniterealtime.org/有你所需要的资料

3、下载Asmack,请猛戳,这个需要自己编译,或者你从其他地方下载相关jar包


Demo下载地址


下面贴出一些关键类:


XmppTool.java主要处理Smack相关数据

package com.example.smackdemo.util;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
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.packet.IQ;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Registration;
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.OfflineMessageManager;
import org.jivesoftware.smackx.PrivateDataManager;
import org.jivesoftware.smackx.ReportedData;
import org.jivesoftware.smackx.ReportedData.Row;
import org.jivesoftware.smackx.bytestreams.ibb.provider.CloseIQProvider;
import org.jivesoftware.smackx.bytestreams.ibb.provider.DataPacketProvider;
import org.jivesoftware.smackx.bytestreams.ibb.provider.OpenIQProvider;
import org.jivesoftware.smackx.bytestreams.socks5.provider.BytestreamsProvider;
import org.jivesoftware.smackx.filetransfer.FileTransfer.Status;
import org.jivesoftware.smackx.filetransfer.FileTransferListener;
import org.jivesoftware.smackx.filetransfer.FileTransferManager;
import org.jivesoftware.smackx.filetransfer.FileTransferRequest;
import org.jivesoftware.smackx.filetransfer.IncomingFileTransfer;
import org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer;
import org.jivesoftware.smackx.muc.DiscussionHistory;
import org.jivesoftware.smackx.muc.HostedRoom;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.muc.RoomInfo;
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 android.os.Environment;
import android.util.Log;

import com.example.smackdemo.SApp;
import com.example.smackdemo.model.MucRoom;
import com.example.smackdemo.model.User;


/***
 * 
 * @author tracyZhang
 *
 */
public class XmppTool {
	
	private String tag = "XmppTool";
	public static final String HOST = "192.168.1.107"; 
	public static final String DOMAIN = "@zhanglei/Smack"; 
	public static final int PORT = 5222; 
	
	private final String CONFERENCE = "@conference.";
	
	private static XmppTool instance;
	private XMPPConnection con;
	
	private MultiUserChat muc;
	
	public MultiUserChat getMuc() {
		return muc;
	}

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


	{
		try {
			Class.forName("org.jivesoftware.smack.ReconnectionManager");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private XmppTool(){
		configure(ProviderManager.getInstance());
		ConnectionConfiguration connConfig = new ConnectionConfiguration(
				HOST, PORT);
		connConfig.setSASLAuthenticationEnabled(false);
		connConfig.setReconnectionAllowed(true);
//		connConfig.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled);
//		connConfig.setSendPresence(true);
		con = new XMPPConnection(connConfig);
		con.DEBUG_ENABLED = true;
		Roster.setDefaultSubscriptionMode(Roster.SubscriptionMode.manual);
		try {
			con.connect();
			
			con.addConnectionListener(new ConnectionListener() {
				
				@Override
				public void reconnectionSuccessful() {
					// TODO Auto-generated method stub
					SLog.i(tag, "重连成功");
				}
				
				@Override
				public void reconnectionFailed(Exception arg0) {
					// TODO Auto-generated method stub
					SLog.i(tag, "重连失败");
				}
				
				@Override
				public void reconnectingIn(int arg0) {
					// TODO Auto-generated method stub
					SLog.i(tag, "重连中");
				}
				
				@Override
				public void connectionClosedOnError(Exception e) {
					// TODO Auto-generated method stub
					SLog.i(tag, "连接出错");
					if(e.getMessage().contains("conflict")){
						SLog.i(tag, "被挤掉了");
						disConnectServer();
					}
				}
				
				@Override
				public void connectionClosed() {
					// TODO Auto-generated method stub
					SLog.i(tag, "连接关闭");
				}
			});
			
		} catch (XMPPException e) {
			SLog.e(tag, Log.getStackTraceString(e));
		}
	}
	
	public XMPPConnection getCon() {
		return con;
	}

	public static XmppTool getInstance(){
		if(null == instance)
			instance = new XmppTool();
		return instance;
	}
	
	public boolean connServer(){
		if(con.isConnected())
			return true;
		try {
			con.connect();
			return true;
		} catch (XMPPException e) {
			SLog.e(tag, Log.getStackTraceString(e));
		}
		return false;
	}
	
	public void disConnectServer(){
		if(null!=con && con.isConnected())
			con.disconnect();
	}
	
	
	/**
	 * 注册
	 * @param name
	 * @param pwd
	 * @return 0 服务端无响应  1成功  2已存在 3 失败
	 */
	public int regist(String name , String pwd){
		
		Registration reg = new Registration();
		reg.setType(IQ.Type.SET);
		reg.setTo(con.getServiceName());
		reg.setUsername(name);
		reg.setPassword(pwd);
		reg.addAttribute("Android", "createUser");
		PacketFilter filter = new AndFilter(new PacketIDFilter(reg.getPacketID()));
		PacketCollector col = con.createPacketCollector(filter);
		con.sendPacket(reg);
		IQ result = (IQ) col.nextResult(SmackConfiguration.getPacketReplyTimeout());
		col.cancel();
		if(null==result){
			SLog.e(tag, "no response from server");
			return 0;
		}else if(result.getType() == IQ.Type.RESULT){
			SLog.e(tag, result.toString());
			return 1;
		}else if(result.getType() == IQ.Type.ERROR){
			SLog.e(tag, result.toString());
			if(result.getError().toString().equalsIgnoreCase("conflict(409)")){
				return 2;
			}else{
				return 3;
			}
		}
		return 3;
	}
	
	/**
	 * 登录
	 * @param name
	 * @param pwd
	 * @return
	 */
	public boolean login(String name,String pwd){
		try {
//			SASLAuthentication.supportSASLMechanism("PLAIN", 0);
			con.login(name, pwd);
			Presence presence = new Presence(Presence.Type.available);
			presence.setMode(Presence.Mode.available);
	        con.sendPacket(presence);
			return true;
		} catch (XMPPException e) {
			SLog.e(tag, Log.getStackTraceString(e));
		}
		return false;
	}
	
	
	/**
	 * 修改密码
	 * @param pwd
	 * @return
	 */
	public boolean changePwd(String pwd){
		try {
			con.getAccountManager().changePassword(pwd);
			return true;
		} catch (XMPPException e) {
			SLog.e(tag, Log.getStackTraceString(e));
		}
		return false;
	}
	
	
	/**
	 * 设置状态
	 * @param state
	 */
	public void setPresence(int state){
		Presence presence;
		switch(state){
		case 0:
			presence = new Presence(Presence.Type.available);
			con.sendPacket(presence);
			SLog.e(tag, "设置在线");
			break;
		case 1:
			presence = new Presence(Presence.Type.available);
			presence.setMode(Presence.Mode.chat);
			con.sendPacket(presence);
			SLog.e(tag, "Q我吧");
			SLog.e(tag, presence.toXML());
			break;
		case 2:
			presence = new Presence(Presence.Type.available);
			presence.setMode(Presence.Mode.dnd);
			con.sendPacket(presence);
			SLog.e(tag, "忙碌");
			SLog.e(tag, presence.toXML());
			break;
		case 3:
			presence = new Presence(Presence.Type.available);
			presence.setMode(Presence.Mode.away);
			con.sendPacket(presence);
			SLog.e(tag, "离开");
			SLog.e(tag, presence.toXML());
			break;
		case 4:
			Roster roster = con.getRoster();
			Collection<RosterEntry> entries = roster.getEntries();
			for(RosterEntry entity:entries){
				presence = new Presence(Presence.Type.unavailable);
				presence.setPacketID(Packet.ID_NOT_AVAILABLE);
				presence.setFrom(con.getUser());
				presence.setTo(entity.getUser());
				con.sendPacket(presence);
				SLog.e(tag, presence.toXML());
			}
			SLog.e(tag, "告知其他用户-隐身");
			
			presence = new Presence(Presence.Type.unavailable);
			presence.setPacketID(Packet.ID_NOT_AVAILABLE);
			presence.setFrom(con.getUser());
			presence.setTo(StringUtils.parseBareAddress(con.getUser()));
			con.sendPacket(presence);
			SLog.e(tag, "告知本用户的其他客户端-隐身");
			SLog.e(tag, presence.toXML());
			break;
		case 5:
			presence = new Presence(Presence.Type.unavailable);
			con.sendPacket(presence);
			SLog.e(tag, "离线");
			SLog.e(tag, presence.toXML());
			break;
		default:
			break;
		}
	}
	
	/**
	 * 删除账号
	 * @return
	 */
	public boolean deleteCount(){
		try {
			con.getAccountManager().deleteAccount();
			return true;
		} catch (XMPPException e) {
			SLog.e(tag, Log.getStackTraceString(e));
		}
		return false;
	}
	
	
	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) {
			Log.w("TestClient",
					"Can't load class for org.jivesoftware.smackx.packet.Time");
		}

		// 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());

		// XHTML
		pm.addExtensionProvider("html", "http://jabber.org/protocol/xhtml-im",
				new XHTMLExtensionProvider());

		// 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) {
			// Not sure what's happening here.
		}

		// 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());

		// FileTransfer
		pm.addIQProvider("si", "http://jabber.org/protocol/si",
				new StreamInitiationProvider());
		pm.addIQProvider("query", "http://jabber.org/protocol/bytestreams",
				new BytestreamsProvider());
		pm.addIQProvider("open", "http://jabber.org/protocol/ibb",
	            new OpenIQProvider());
	    pm.addIQProvider("close", "http://jabber.org/protocol/ibb",
	            new CloseIQProvider());
	    pm.addExtensionProvider("data", "http://jabber.org/protocol/ibb",
	            new DataPacketProvider());

		// Privacy
		pm.addIQProvider("query", "jabber:iq:privacy", new PrivacyProvider());
		pm.addIQProvider("command", "http://jabber.org/protocol/commands",
				new AdHocCommandDataProvider());
		pm.addExtensionProvider("malformed-action",
				"http://jabber.org/protocol/commands",
				new AdHocCommandDataProvider.MalformedActionError());
		pm.addExtensionProvider("bad-locale",
				"http://jabber.org/protocol/commands",
				new AdHocCommandDataProvider.BadLocaleError());
		pm.addExtensionProvider("bad-payload",
				"http://jabber.org/protocol/commands",
				new AdHocCommandDataProvider.BadPayloadError());
		pm.addExtensionProvider("bad-sessionid",
				"http://jabber.org/protocol/commands",
				new AdHocCommandDataProvider.BadSessionIDError());
		pm.addExtensionProvider("session-expired",
				"http://jabber.org/protocol/commands",
				new AdHocCommandDataProvider.SessionExpiredError());
	}
	
	
	/**
	 * 获取所有分组
	 * @param roster
	 * @return
	 */
	public List<RosterGroup> getGroups(Roster roster){
		List<RosterGroup> list = new ArrayList<RosterGroup>();
		list.addAll(roster.getGroups());
		return list;
	}
	
	/**
	 * 添加分组
	 * @param roster
	 * @param groupName
	 * @return
	 */
	public boolean addGroup(Roster roster,String groupName){
		try{
			roster.createGroup(groupName);
			return true;
		}catch(Exception e){
			SLog.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) {
			SLog.e(tag, Log.getStackTraceString(e));
		}
	}
	
	
	/**
	 * 获取所有成员
	 * @param roster
	 * @return
	 */
	public List<RosterEntry> getAllEntrys(Roster roster){
		List<RosterEntry> list = new ArrayList<RosterEntry>();
		list.addAll(roster.getEntries());
		return list;
	}
	
	/**
	 * 获取某一个分组的成员
	 * @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;
	}
	
	/**
	 *  获取用户VCard信息
	 * @param user
	 * @return
	 */
	public VCard getVCard(String user){
		VCard vCard = new VCard();
		try {
			vCard.load(con, user);
		} catch (XMPPException e) {
			SLog.e(tag, Log.getStackTraceString(e));
			return null;
		}
		return vCard;
	}
	
	/**
	 * 添加好友
	 * @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) {
			SLog.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) {
			SLog.e(tag, Log.getStackTraceString(e));
		}
		return false;
	}
	
	
	/**
	 * 查找用户
	 * @param serverDomain
	 * @param userName
	 * @return
	 */
	public List<User> searchUsers(String serverDomain,String userName){
		List<User> list = new ArrayList<User>();
		UserSearchManager userSearchManager = new UserSearchManager(con);
		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()){
				User user = new User();
				Row row = rows.next();
				user.setUserName(row.getValues("Username").next().toString());
				user.setName(row.getValues("Name").next().toString());
				SLog.i(tag, user.toString());
				list.add(user);
			}
		} catch (XMPPException e) {
			SLog.e(tag, Log.getStackTraceString(e));
		}
		return list;
	}
	
	/**
	 * 发送文件
	 * @param recvUser
	 * @param filePath
	 */
	public void sendFile(String recvUser,String filePath){
		FileTransferManager fileTransferManager = new FileTransferManager(con);
		try {
			final OutgoingFileTransfer outgoingFileTransfer =  fileTransferManager.createOutgoingFileTransfer(recvUser);
			SLog.i(tag, "上送文件"+filePath);
			outgoingFileTransfer.sendFile(new File(filePath),"outgoingFileTransfer ^_^");
			SApp.getInstance().execRunnable(new Runnable(){
				@Override
				public void run() {
					while (!outgoingFileTransfer.isDone()) {  
			            SLog.i(tag,"进度:"+outgoingFileTransfer.getProgress());
			            try {
							Thread.sleep(100);
						} catch (InterruptedException e) {
							SLog.e(tag, Log.getStackTraceString(e));
						}
			        }
					SLog.i(tag,"上送状态"+outgoingFileTransfer.getStatus());
					if(outgoingFileTransfer.getStatus().equals(Status.complete))
						SLog.i(tag,"上送完毕");
					else if(outgoingFileTransfer.getStatus().equals(Status.error))
						SLog.i(tag,"上送出错");
				}});
		} catch (XMPPException e) {
			SLog.i(tag, "上送文件异常");
			SLog.e(tag, Log.getStackTraceString(e));
		}
	}
	
	
	/**
	 * 注册文件接收器
	 */
	public void registRecvFileListener(){
		FileTransferManager fileTransferManager = new FileTransferManager(con);
		fileTransferManager.addFileTransferListener(new FileTransferListener() {  
            public void fileTransferRequest(final FileTransferRequest request) {  
            	final IncomingFileTransfer transfer = request.accept();  
                try{  
                    SLog.i(tag,"接受文件:"+transfer.getFileName());  
                    transfer.recieveFile(new File(Environment.getExternalStorageDirectory()+"/"+request.getFileName()));
                    SApp.getInstance().execRunnable(new Runnable(){
						@Override
						public void run() {
							while (!transfer.isDone()) {  
		        	            SLog.i(tag,"进度:"+transfer.getProgress());
		        	            try {
		        					Thread.sleep(100);
		        				} catch (InterruptedException e) {
		        					SLog.e(tag, Log.getStackTraceString(e));
		        				}
		        	        }
		        			SLog.i(tag,"接受状态"+transfer.getStatus());
		        			if(transfer.getStatus().equals(Status.complete))
		        				SLog.i(tag,"接受完毕");
		        			else if(transfer.getStatus().equals(Status.error)){
		        				transfer.cancel();
		        				SLog.i(tag,"接受出错");
		        			}
						}});
                }catch(Exception e){  
                	SLog.e(tag, Log.getStackTraceString(e));
                	SLog.e(tag, "文件接收出错");
                	transfer.cancel();
                }  
            }  
        });
	}
	
	
	/**
	 * 获取离线消息
	 * @return
	 */
	public List<Message> getOffLineMessages(){
		List<Message> msgs = new ArrayList<Message>();
		OfflineMessageManager offLineMessageManager = new OfflineMessageManager(con);
		try {
			Iterator<Message> it = offLineMessageManager.getMessages();
			while(it.hasNext()){
				Message msg = it.next();
				SLog.i(tag, msg.toXML());
				msgs.add(msg);
			}
			offLineMessageManager.deleteMessages();
		} catch (XMPPException e) {
			e.printStackTrace();
		}
		return msgs;
	}
	
	
	
	/**
	 * 创建会议室 
	 * @param roomName
	 * @param roomPwd 会议室密码
	 */
	public boolean createRoom(String roomName , String roomPwd , String subject){
		MultiUserChat multiUserChat  = new MultiUserChat(con,roomName+CONFERENCE+con.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(con.getUser());
			submitForm.setAnswer("muc#roomconfig_roomowners", owners);
			submitForm.setAnswer("muc#roomconfig_persistentroom", false);
			submitForm.setAnswer("muc#roomconfig_membersonly", false);
			submitForm.setAnswer("muc#roomconfig_allowinvites", true);
			submitForm.setAnswer("muc#roomconfig_passwordprotectedroom", true);
			submitForm.setAnswer("muc#roomconfig_roomsecret", roomPwd);
			submitForm.setAnswer("muc#roomconfig_enablelogging", true);
			submitForm.setAnswer("muc#roomconfig_roomdesc", subject);
			
			multiUserChat.sendConfigurationForm(submitForm);
			
			
		} catch (XMPPException e) {
			SLog.e(tag, "创建聊天室 出错");
			SLog.e(tag, Log.getStackTraceString(e));
			return false;
		}
		return true;
	}
	
	/**
	 * 加入聊天室
	 * @param user
	 * @param pwd 会议室密码
	 * @param roomName
	 * @return
	 */
	public MultiUserChat joinRoom(String user,String pwd,String roomName){
		MultiUserChat muc = new MultiUserChat(con,roomName.contains(CONFERENCE)?roomName:roomName+CONFERENCE+con.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());
			Message msg = muc.nextMessage();
			if(null!=msg)
				SLog.i(tag, msg.toXML());
			
			Message msg2 = muc.nextMessage(100);
			if(null!=msg2)
				SLog.i(tag, msg2.toXML());
			
		} catch (XMPPException e) {
			SLog.e(tag, " 加入 聊天室 出错");
			SLog.e(tag, Log.getStackTraceString(e));
			return null;
		}
		return muc;
	}
	
	/**
	 * 获取会议室成员名字
	 * @param muc
	 * @return
	 */
	public List<String> getMUCMembers(MultiUserChat muc){
		List<String> members = new ArrayList<String>();
		Iterator<String> it = muc.getOccupants();
		while(it.hasNext()){
			String name = StringUtils.parseResource(it.next());
			SLog.i("成员名字", name);
			members.add(name);
		}
		return members;
	}
	
	
	/**
	 * 获取Hostedrooms
	 * @return
	 */
	public List<MucRoom> getAllHostedRooms(){
		List<MucRoom> rooms = new ArrayList<MucRoom>();
		try {
			Collection<HostedRoom> hrooms = MultiUserChat.getHostedRooms(con, con.getServiceName());
			if(!hrooms.isEmpty()){
				for(HostedRoom r:hrooms){
					RoomInfo roominfo = MultiUserChat.getRoomInfo(con, r.getJid());
					SLog.i("会议室Info", roominfo.toString());
					MucRoom mr = new MucRoom();
					mr.setDescription(roominfo.getDescription());
					mr.setName(r.getName());
					mr.setJid(r.getJid());
					mr.setOccupants(roominfo.getOccupantsCount());
					mr.setSubject(roominfo.getSubject());
					rooms.add(mr);
				}
			}
		} catch (XMPPException e) {
			SLog.e(tag, " 获取Hosted Rooms 出错");
			SLog.e(tag, Log.getStackTraceString(e));
		}
		return rooms;
	}
	
	public List<MucRoom> getJoinedRooms(){
		List<MucRoom> rooms = new ArrayList<MucRoom>();
		Iterator<String> jrs = MultiUserChat.getJoinedRooms(con, con.getUser());
		return rooms;
	}
	
	
	/**
	 * 创建给予聊天室的私聊
	 * @param participant   myroom@conference.jabber.org/johndoe
	 * @param listener
	 * @return
	 */
	public Chat createPrivateChat(String participant , MessageListener listener){
		return muc.createPrivateChat(participant, listener);
	}
	
	/**
	 * 用户是否支持聊天室
	 * @param user
	 * @return
	 */
//	public boolean isUserSupportMUC(String user){
//		return MultiUserChat.isServiceEnabled(con, user);
//	}
	
	/**
	 * 离开聊天室
	 */
	public void leaveRoom(){
		if(null!=muc)
			muc.leave();
		muc = null;
	}

}


Regist.java处理注册相关逻辑

package com.example.smackdemo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import com.example.smackdemo.util.SLog;
import com.example.smackdemo.util.XmppTool;

public class Regist extends Activity {
	
	private String tag = "Regist";
	
	Handler handler = new Handler(){

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch(msg.what){
			case 1:
				SLog.i(tag, "成功");
				Toast.makeText(Regist.this, "注册成功", Toast.LENGTH_SHORT).show();
				finish();
				break;
			case 2:
				SLog.i(tag, "用户已存在");
				Toast.makeText(Regist.this, "用户已存在", Toast.LENGTH_SHORT).show();
				break;
			case 0:
				SLog.i(tag, "服务器无响应");
				Toast.makeText(Regist.this, "服务器无响应", Toast.LENGTH_SHORT).show();
				break;
			default:
				SLog.i(tag, "注册失败");
				Toast.makeText(Regist.this, "注册失败", Toast.LENGTH_SHORT).show();
				break;
			}
		}
		
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.regist);
	}
	
	public void regist(View v){
		EditText nameEt = (EditText) findViewById(R.id.userName);
		EditText pwdEt = (EditText) findViewById(R.id.pwd);
		final String name = nameEt.getText().toString();
		final String pwd = pwdEt.getText().toString();
		SApp.getInstance().execRunnable(new Runnable(){
			@Override
			public void run() {
				int result = XmppTool.getInstance().regist(name, pwd);
				SLog.i(tag, String.valueOf(result));
				handler.sendEmptyMessage(result);
			}});
	}

}


Login.java登录

package com.example.smackdemo;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import com.example.smackdemo.service.PresenceService;
import com.example.smackdemo.util.SLog;
import com.example.smackdemo.util.XmppTool;

public class Login extends Activity {
	
private String tag = "Login";
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.login);
	}
	
	public void login(View v){
		
		EditText nameEt = (EditText) findViewById(R.id.userName);
		EditText pwdEt = (EditText) findViewById(R.id.pwd);
		final String name = nameEt.getText().toString();
		final String pwd = pwdEt.getText().toString();
		SApp.getInstance().execRunnable(new Runnable(){
			@Override
			public void run() {
				boolean result = XmppTool.getInstance().login(name, pwd);
				SLog.i(tag, String.valueOf(result));
				if(result){
//					XmppTool.getInstance().setPresence(0);
					XmppTool.getInstance().registRecvFileListener();
					startActivity(new Intent(Login.this,MyHome.class));
					startService(new Intent(Login.this,PresenceService.class));
					finish();
				}else{
					runOnUiThread(new Runnable(){
						@Override
						public void run() {
							Toast.makeText(Login.this, "登陆失败", Toast.LENGTH_LONG).show();
						}});
				}
			}});
		
	}

}

MyHome.java我的主页,列出了好友及分组情况,菜单下有一些操作:搜索、聊天室等,同时添加了消息监听、聊天室邀请监听

package com.example.smackdemo;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import org.jivesoftware.smack.RosterListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smackx.muc.InvitationListener;
import org.jivesoftware.smackx.muc.MultiUserChat;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.Toast;

import com.example.smackdemo.adapter.MyFriendExpadableAdapter;
import com.example.smackdemo.util.MyChatManagerListener;
import com.example.smackdemo.util.SLog;
import com.example.smackdemo.util.XmppTool;

public class MyHome extends Activity implements OnChildClickListener, InvitationListener {
	
	private String tag = "MyHome";
	private ExpandableListView exList;
	private XMPPConnection con;
	private List<RosterGroup> groups;
	private MyFriendExpadableAdapter adapter;
	private Map<RosterGroup,List<RosterEntry>> childs;
	private ChatManager chatManager;
	private Roster roster;
	
	Handler handler = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch(msg.what){
			case 1:
				setAdapter();
				break;
			}
		}
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.my_home);
		exList = (ExpandableListView) findViewById(R.id.exList);
		exList.setOnChildClickListener(this);
		con = XmppTool.getInstance().getCon();
		chatManager = con.getChatManager();
		chatManager.addChatListener(new MyChatManagerListener(this));
		roster = con.getRoster();
		roster.addRosterListener(new RosterListener() {
			
			@Override
			public void presenceChanged(Presence p) {
				// TODO Auto-generated method stub
				SLog.i(tag, "presenceChanged--"+p.toXML());
			}
			
			@Override
			public void entriesUpdated(Collection<String> c) {
				// TODO Auto-generated method stub
				SLog.i(tag, "entriesUpdated--");
			}
			
			@Override
			public void entriesDeleted(Collection<String> c) {
				// TODO Auto-generated method stub
				SLog.i(tag, "entriesDeleted--");
			}
			
			@Override
			public void entriesAdded(Collection<String> arg0) {
				// TODO Auto-generated method stub
				SLog.i(tag, "entriesAdded--");
			}
		});
		MultiUserChat.addInvitationListener(con, this);
		initData();
	}
	
	protected void setAdapter() {
		adapter = new MyFriendExpadableAdapter(this,groups,childs);
		exList.setAdapter(adapter);
	}

	private void initData(){
		SApp.getInstance().execRunnable(new Runnable(){
			@Override
			public void run() {
				groups = XmppTool.getInstance().getGroups(roster);
				childs = new HashMap<RosterGroup,List<RosterEntry>>();
				for(RosterGroup g:groups){
					SLog.i(tag, g.toString());
					List<RosterEntry> child = XmppTool.getInstance().getEntrysByGroup(roster, g.getName());
					childs.put(g, child);
				}
				handler.sendEmptyMessage(1);
			}});
	}

	@Override
	public boolean onChildClick(ExpandableListView parent, View v,
			int groupPosition, int childPosition, long id) {
		// TODO Auto-generated method stub
		RosterEntry child = (RosterEntry) adapter.getChild(groupPosition, childPosition);
		Intent intent = new Intent(this,ChatActivity.class);
		intent.putExtra("userId", child.getUser());
		startActivityForResult(intent,1);
		return false;
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuItem item = menu.add(0, 0, 0, "Search");
		MenuItem item2 = menu.add(1, 1, 1, "离线消息");
		menu.add(2, 2, 2, "更改状态");
		menu.add(3, 3, 3, "聊天室");
		item.setIcon(android.R.drawable.ic_menu_search);
		item2.setIcon(android.R.drawable.ic_menu_more);
		return super.onCreateOptionsMenu(menu);
	}
	
	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		if(item.getItemId() ==0){
			Intent intent = new Intent(this,Search.class);
			startActivityForResult(intent,1);
		}else if(item.getItemId() == 1){
			XmppTool.getInstance().getOffLineMessages();
		}else if(item.getItemId() == 2){
		}else if(item.getItemId() == 3){
			startActivity(new Intent(this,MUCActivity.class));
		}
		return super.onMenuItemSelected(featureId, item);
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if(1 == resultCode && 1==requestCode){
			initData();
		}
	}
	

	@Override
	public void invitationReceived(Connection conn, final String room, final String inviter, String reason, final String password, org.jivesoftware.smack.packet.Message msg) {
		// TODO Auto-generated method stub
		SLog.i(tag, "room:"+room+" , inviter:" +inviter+" , reason" + reason +" , password:"+password+" , msg:"+msg.toXML());
		
		final AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("选择好友");
		builder.setMessage(inviter+" 邀请我加入 "+room);
		builder.setPositiveButton("加入", new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				dialog.cancel();
				
				MultiUserChat tmp = XmppTool.getInstance().joinRoom(con.getUser(), password, room);
				if(null!=tmp){
					if(null!=XmppTool.getInstance().getMuc()){
						XmppTool.getInstance().leaveRoom();
						XmppTool.getInstance().setMuc(tmp);
						Toast.makeText(MyHome.this, "切换房间成功", Toast.LENGTH_SHORT).show();
						SLog.i(tag, "重新初始化房间.....");
						startActivity(new Intent(MyHome.this,MUCRoom.class));
					}else{
						XmppTool.getInstance().setMuc(tmp);
						startActivity(new Intent(MyHome.this,MUCRoom.class));
					}
				}else{
					Toast.makeText(MyHome.this, "进入新房间失败", Toast.LENGTH_SHORT).show();
					SLog.i(tag, "呆着不动.....");
				}
			}
		});
		builder.setNeutralButton("拒绝", new DialogInterface.OnClickListener(){

			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				dialog.cancel();
				MultiUserChat.decline(con, room, inviter, "I'm too busy");
			}});
		
		runOnUiThread(new Runnable(){

			@Override
			public void run() {
				// TODO Auto-generated method stub
				builder.create().show();
			}});
		
	}
	
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		MultiUserChat.removeInvitationListener(con, this);
		super.onDestroy();
	}

}

MUCRoom.java聊天室,聊天室的成员、聊天内容、邀请好友、踢人等

package com.example.smackdemo;

import java.util.Date;
import java.util.List;

import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.muc.InvitationListener;
import org.jivesoftware.smackx.muc.InvitationRejectionListener;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.muc.Occupant;
import org.jivesoftware.smackx.muc.ParticipantStatusListener;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.example.smackdemo.model.MucHistory;
import com.example.smackdemo.util.SLog;
import com.example.smackdemo.util.XmppTool;

public class MUCRoom extends Activity implements InvitationRejectionListener, InvitationListener, ParticipantStatusListener, PacketListener, OnItemClickListener {
	
	private String tag = "MUCRoom";
	
	ListView membersList , chatsList;
	TextView subject;
	EditText content;
	XMPPConnection con;
	MultiUserChat muc;
	
	List<String> membersName;
	
	SApp app;
	MemberAdapter mAdapter;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.muc_room);
		con = XmppTool.getInstance().getCon();
		muc = XmppTool.getInstance().getMuc();
		muc.addInvitationRejectionListener(this);
		MultiUserChat.addInvitationListener(con, this);
		muc.addParticipantStatusListener(this);
		muc.addMessageListener(this);
		app = SApp.getInstance();
		membersList = (ListView) findViewById(R.id.members);
		chatsList = (ListView) findViewById(R.id.chats);
		content = (EditText) findViewById(R.id.content);
		membersList.setOnItemClickListener(this);
		initData();
		
	}
	
	class MemberAdapter extends BaseAdapter{

		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return membersName.size();
		}

		@Override
		public Object getItem(int arg0) {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public long getItemId(int arg0) {
			// TODO Auto-generated method stub
			return 0;
		}

		@Override
		public View getView(int arg0, View view, ViewGroup arg2) {
			// TODO Auto-generated method stub
			if(null == view){
				view = LayoutInflater.from(MUCRoom.this).inflate(android.R.layout.simple_list_item_1, null);
			}
			TextView text = (TextView) view.findViewById(android.R.id.text1);
			text.setText(membersName.get(arg0));
			return view;
		}
		
	}
	
	private void initData(){
		app.execRunnable(new Runnable(){
			@Override
			public void run() {
				// TODO Auto-generated method stub
				membersName = XmppTool.getInstance().getMUCMembers(muc);
				mAdapter = new MemberAdapter();
				
				runOnUiThread(new Runnable(){

					@Override
					public void run() {
						// TODO Auto-generated method stub
						membersList.setAdapter(mAdapter);
					}});
				
			}});
		
	}
	
	public void invite(View v){
		final List<RosterEntry> friends = XmppTool.getInstance().getAllEntrys(con.getRoster());
		String[] names = new String[friends.size()];
		for(int i=0;i<friends.size();i++){
			RosterEntry entry = friends.get(i);
			names[i] = entry.getName();
		}
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("选择好友");
		builder.setItems(names, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int pos) {
				// TODO Auto-generated method stub
				dialog.cancel();
//				if(XmppTool.getInstance().isUserSupportMUC(friends.get(pos).getUser()))
					muc.invite(friends.get(pos).getUser(), "加入我的会议室吧");
//				else
//					Toast.makeText(MUCRoom.this, "该好友设置了不加入会议室", Toast.LENGTH_SHORT).show();
			}
		});
		builder.create().show();
	}
	
	public void send(View v){
		try {
			muc.sendMessage(content.getText().toString());
			content.setText("");
		} catch (XMPPException e) {
			SLog.e(tag, Log.getStackTraceString(e));
		}
	}
	
	@Override
	protected void onDestroy() {
		XmppTool.getInstance().leaveRoom();
		MultiUserChat.removeInvitationListener(con, this);
		super.onDestroy();
	}

	@Override
	public void invitationDeclined(final String invitee, final String reason) {
		// TODO Auto-generated method stub
		SLog.i(tag, "被邀请者:"+invitee+" , 原因:"+reason);
		runOnUiThread(new Runnable(){

			@Override
			public void run() {
				// TODO Auto-generated method stub
				Toast.makeText(MUCRoom.this, "被邀请者:"+invitee+" , 原因:"+reason, Toast.LENGTH_SHORT).show();
			}});
	}

	@Override
	public void invitationReceived(Connection conn, final String room, final String inviter, String reason, final String password, Message msg) {
		// TODO Auto-generated method stub
		SLog.i(tag, "room:"+room+" , inviter:" +inviter+" , reason" + reason +" , password:"+password+" , msg:"+msg.toXML());
		
		final AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("选择好友");
		builder.setMessage(inviter+" 邀请我加入 "+room);
		builder.setPositiveButton("加入", new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				dialog.cancel();
				
				MultiUserChat tmp = XmppTool.getInstance().joinRoom(con.getUser(), password, room);
				if(null!=tmp){
					XmppTool.getInstance().leaveRoom();
					XmppTool.getInstance().setMuc(tmp);
					Toast.makeText(MUCRoom.this, "切换房间成功", Toast.LENGTH_SHORT).show();
					SLog.i(tag, "重新初始化房间.....");
				}else{
					Toast.makeText(MUCRoom.this, "进入新房间失败", Toast.LENGTH_SHORT).show();
					SLog.i(tag, "呆着不动.....");
				}
			}
		});
		builder.setNeutralButton("拒绝", new DialogInterface.OnClickListener(){

			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				dialog.cancel();
				MultiUserChat.decline(con, room, inviter, "I'm too busy");
			}});
		
		runOnUiThread(new Runnable(){

			@Override
			public void run() {
				// TODO Auto-generated method stub
				builder.create().show();
			}});
	}
	
	private void showToast(final String msg){
		runOnUiThread(new Runnable(){
			@Override
			public void run() {
				// TODO Auto-generated method stub
				Toast.makeText(MUCRoom.this, msg, Toast.LENGTH_SHORT).show();
			}});
		
	}
	
	@Override
	public void adminGranted(String arg0) {
		// TODO Auto-generated method stub
		SLog.i(tag, "adminGranted"+arg0);
		showToast("adminGranted"+arg0);
	}

	@Override
	public void adminRevoked(String arg0) {
		// TODO Auto-generated method stub
		SLog.i(tag, "adminRevoked"+arg0);
		showToast("adminRevoked"+arg0);
	}

	@Override
	public void banned(String arg0, String arg1, String arg2) {
		// TODO Auto-generated method stub
		SLog.i(tag, "banned"+arg0+","+arg1+","+arg2);
		showToast("banned"+arg0+","+arg1+","+arg2);
		initData();
	}

	@Override
	public void joined(String arg0) {
		// TODO Auto-generated method stub
		SLog.i(tag, "joined"+arg0);
		showToast("joined"+arg0);
		initData();
	}

	@Override
	public void kicked(String arg0, String arg1, String arg2) {
		// TODO Auto-generated method stub
		SLog.i(tag, "kicked"+arg0+" , "+arg1+" , "+arg2);
		showToast("kicked"+arg0+" , "+arg1+" , "+arg2);
		initData();
	}

	@Override
	public void left(String arg0) {
		// TODO Auto-generated method stub
		SLog.i(tag, "left"+arg0);
		showToast("left"+arg0);
		initData();
	}

	@Override
	public void membershipGranted(String arg0) {
		// TODO Auto-generated method stub
		SLog.i(tag, "membershipGranted"+arg0);
		showToast( "membershipGranted"+arg0);
	}

	@Override
	public void membershipRevoked(String arg0) {
		// TODO Auto-generated method stub
		SLog.i(tag, "membershipRevoked"+arg0);
		showToast("membershipRevoked"+arg0);
	}

	@Override
	public void moderatorGranted(String arg0) {
		// TODO Auto-generated method stub
		SLog.i(tag, "moderatorGranted"+arg0);
		showToast("moderatorGranted"+arg0);
	}

	@Override
	public void moderatorRevoked(String arg0) {
		// TODO Auto-generated method stub
		SLog.i(tag, "moderatorRevoked"+arg0);
		showToast("moderatorRevoked"+arg0);
	}

	@Override
	public void nicknameChanged(String arg0, String arg1) {
		// TODO Auto-generated method stub
		SLog.i(tag, "nicknameChanged"+arg0);
		showToast("nicknameChanged"+arg0);
	}

	@Override
	public void ownershipGranted(String arg0) {
		// TODO Auto-generated method stub
		SLog.i(tag, "ownershipGranted"+arg0);
		showToast("ownershipGranted"+arg0);
	}

	@Override
	public void ownershipRevoked(String arg0) {
		// TODO Auto-generated method stub
		SLog.i(tag, "ownershipRevoked"+arg0);
		showToast("ownershipRevoked"+arg0);
	}

	@Override
	public void voiceGranted(String arg0) {
		// TODO Auto-generated method stub
		SLog.i(tag, "voiceGranted"+arg0);
		showToast("voiceGranted"+arg0);
	}

	@Override
	public void voiceRevoked(String arg0) {
		// TODO Auto-generated method stub
		SLog.i(tag, "voiceRevoked"+arg0);
		showToast( "voiceRevoked"+arg0);
	}

	@Override
	public void processPacket(Packet packet) {
		// TODO Auto-generated method stub
		SLog.i(tag, packet.toXML());
		Message msg = (Message) packet;
		String from = StringUtils.parseResource(msg.getFrom());
		showToast(from+" 说:"+msg.getBody());
		
	}

	private String[] memberActions = {"私聊","踢了他"};
	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1, final int pos, long arg3) {
		// TODO Auto-generated method stub
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("请选择");
		builder.setItems(memberActions, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				dialog.cancel();
				if(0==which){
					
				}else if(1==which){
					try {
						String jid = membersName.get(pos);
						SLog.i(tag, " jid:"+jid);
						muc.banUser(jid.contains(XmppTool.DOMAIN)?jid:jid+XmppTool.DOMAIN, "你被踢了");
					} catch (XMPPException e) {
						SLog.e(tag, Log.getStackTraceString(e));
					}
				}
			}
		});
		builder.create().show();
		
	}

}


ChatActivity.java与好友聊天页面,可以互发消息,互传文件,Android手机端需要sd卡下放置一个测试文件tmp.txt注意要有内容

package com.example.smackdemo;

import java.io.File;
import java.io.IOException;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.FromContainsFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import com.example.smackdemo.util.MyChatManagerListener;
import com.example.smackdemo.util.SLog;
import com.example.smackdemo.util.XmppTool;

public class ChatActivity extends Activity implements ChatManagerListener, PacketListener {
	
	private String tag = "ChatActivity";
	
	private ListView listview;
	private EditText replyContent;
	private String userId;
	
	private XMPPConnection con;
	private ChatManager chatManager;
	private Chat chat;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.chat);
		userId = getIntent().getStringExtra("userId");
		setTitle(String.format(getString(R.string.chatTitle), userId));
		initViews();
		initData();
	}

	private void initData() {
		con = XmppTool.getInstance().getCon();
		chatManager = con.getChatManager();
		chat = chatManager.createChat(userId,null);
		
//		chatManager.addChatListener(this);
//		chat = chatManager.createChat(userId,new MessageListener(){
//			@Override
//			public void processMessage(Chat arg0, Message message) {
//				SLog.i(tag, message.getFrom()+" 说:"+message.getBody());
//				Toast.makeText(ChatActivity.this, message.getFrom()+" 说:"+message.getBody(), Toast.LENGTH_SHORT).show();
//			}});
//		PacketFilter filter = new AndFilter(new PacketTypeFilter(Message.class),new FromContainsFilter(userId));
//		PacketCollector packetCollector = con.createPacketCollector(filter);
//		con.addPacketListener(this, filter);
		
	}

	private void initViews() {
		listview = (ListView) findViewById(R.id.listview);
		replyContent = (EditText) findViewById(R.id.replyContent);
	}
	
	public void send(View v){
		try {
			chat.sendMessage(replyContent.getText().toString());
//			Message newMessage = new Message();
//			newMessage.setBody(replyContent.getText().toString());
//			newMessage.setProperty("favoriteColor", "red");
//			chat.sendMessage(newMessage);
			replyContent.setText("");
		} catch (XMPPException e) {
			SLog.e(tag, Log.getStackTraceString(e));
			Toast.makeText(this, "发送失败", Toast.LENGTH_SHORT).show();
		} 
	}

	@Override
	public void chatCreated(Chat chat, boolean createdLocally) {
//		SLog.i(tag, "chatCreated");
	}

	@Override
	public void processPacket(Packet packet) {
//		SLog.i(tag, packet.toString());
	}
	
	public void sendFile(View v){
		File tmpFile = new File(Environment.getExternalStorageDirectory()+"/tmp.txt");
		if(!tmpFile.exists())
			try {
				tmpFile.createNewFile();
			} catch (IOException e) {
				SLog.i(tag, Log.getStackTraceString(e));
			}
		XmppTool.getInstance().sendFile(userId+"/Spark 2.6.3", tmpFile.getPath());
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		menu.add(0, 0, 0, "删除好友");
		return super.onCreateOptionsMenu(menu);
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		boolean result = XmppTool.getInstance().removeUser(con.getRoster(), userId);
		if(result){
			Toast.makeText(this, "删除好友成功", Toast.LENGTH_SHORT).show();
			setResult(1);
			finish();
		}else
			Toast.makeText(this, "删除好友失败", Toast.LENGTH_SHORT).show();
		return super.onOptionsItemSelected(item);
	}

}



评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值