接口定义请参考上篇,实现接口采用的是成熟的第三方asmack包,asmack是smack的android版,而smack是一个已经相对成熟的封装xmpp协议的第三方jar包。服务器端安装openfire服务器,通过调用asmack的相关接口可以进行用户间通信。
在写代码之前先简单介绍几个常用类
1:ConnectionConfiguration 这是一个xmpp连接的配置类 可以通过 ConnectionConfiguration imConfig = new ConnectionConfiguration(IMConfig.IMSERVER, IMConfig.IMPORT); 配置服务器的ip和接口。
2: XMPPConnection xmpp连接管理类,通过ConnectionConfiguration 配置好相关设置后,通过imConnection = new XMPPConnection(imConfig);创建一个新的连接。
3: Roster roster相当于联系人列表,里面存储了联系人相关信息。
4:Preference 状态:分为:在线,离线,等。(4种状态)。
具体接口实现代码如下:
public class IMChat implements IMChatImpl { protected static final String TAG = "IMChat"; private Context iContext; private static IMChat chatInstance = null; private ConnectionConfiguration imConfig; private XMPPConnection imConnection; private Roster roster; private FileTransferManager fileTransferManager; private ArrayList<FriendRoster> friendList; private RecentDao recentDao; private MessageDao messageDao; /** * 保持自动重连 */ static { try { Class.forName("org.jivesoftware.smack.ReconnectionManager"); } catch (ClassNotFoundException ex) { // problem loading reconnection manager } } private IMChat(Context context) { iContext = context.getApplicationContext(); initIMConnection(); } private void initIMConnection() { recentDao = new RecentDao(iContext); messageDao = new MessageDao(iContext); imConfig = new ConnectionConfiguration(IMConfig.IMSERVER, IMConfig.IMPORT); imConfig.setCompressionEnabled(false); imConfig.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled); imConfig.setReconnectionAllowed(true); imConfig.setSendPresence(true); imConfig.setDebuggerEnabled(false); chatConfig(); imConnection = new XMPPConnection(imConfig); } private void chatConfig() { ProviderManager pm = ProviderManager.getInstance(); // 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()); // 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()); pm.addIQProvider("vCard", "vcard-temp", new VCardProvider()); 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()); // Privacy pm.addIQProvider("query", "jabber:iq:privacy", new PrivacyProvider()); } public static IMChat getInstace(Context context) { if (chatInstance == null) chatInstance = new IMChat(context); return chatInstance; } /** * 通过Roster获取联系人列表 * * @return 联系人的ArrayList */ public ArrayList<FriendRoster> getFriends() { friendList = new ArrayList<FriendRoster>(); FriendRoster friendRoster; Collection<RosterEntry> rosterEntries = roster.getEntries(); for (RosterEntry friendEntry : rosterEntries) { String friendJid = friendEntry.getUser(); String friendAlias = friendEntry.getName(); friendRoster = new FriendRoster(friendJid, friendAlias); friendList.add(friendRoster); } return friendList; } @Override public boolean login(String account, String password) { if (imConnection.isConnected()) imConnection.disconnect(); try { imConnection.connect(); imConnection.login(account, password); } catch (XMPPException e) { e.printStackTrace(); return false; } if (imConnection.isAuthenticated()) { roster = imConnection.getRoster(); roster.setSubscriptionMode(Roster.SubscriptionMode.accept_all); initMessageListener(); initFileListener(); return true; } return false; } /** * 注册消息的监听器 */ private void initMessageListener() { imConnection.getChatManager().addChatListener( new ChatManagerListener() { @Override public void chatCreated(Chat chat, boolean createdLocally) { chat.addMessageListener(messageListener); } }); } /** * 创建文本消息的监听器(new) */ private MessageListener messageListener = new MessageListener() { @Override public void processMessage(Chat chat, Message message) { if (message.getType() == Message.Type.chat) { String fromId = message.getFrom(); System.out.println(fromId); fromId = fromId.split("@")[0]; String friendAlias = getFriendName(fromId); String msgContent = message.getBody(); String msgTime = DateTime.getSimpleTime(); addRecentMessageDao(fromId, friendAlias, msgTime, msgContent, ChatMessage.MSG_TYPE_TXT_IN); } } }; /** * 数据库内添加最近聊天文字信息 * * @param chatAccount * @param chatUser * @param msgTime * @param msgContent */ private void addRecentMessageDao(String chatAccount, String chatUser, String msgTime, String msgContent, int msgType) { ChatMessage chatMessage = new ChatMessage(); chatMessage.setMsgAccount(chatAccount); chatMessage.setMsgUser(chatUser); chatMessage.setMsgTime(msgTime); chatMessage.setMsgContent(msgContent); chatMessage.setMsgType(msgType); messageDao.insert(chatMessage); if (msgType == ChatMessage.MSG_TYPE_IMG_IN) { msgContent = "[图片]"; } else if (msgType == ChatMessage.MSG_TYPE_VOICE_IN) { msgContent = "[语音]"; } RecentChat recentChat = new RecentChat(chatAccount, null, chatUser, msgTime, msgContent); recentDao.insert(recentChat); Intent intent = new Intent(IMConfig.MSG_ACTION); intent.putExtra(IMConfig.CHAT_ACCOUNT, chatAccount); intent.putExtra(IMConfig.CHAT_USERNAME, chatUser); intent.putExtra(IMConfig.CHAT_CONTENT,msgContent); iContext.sendBroadcast(intent); } /** * 注册接收文件的监听器 */ private void initFileListener() { fileTransferManager = new FileTransferManager(imConnection); fileTransferManager.addFileTransferListener(new FileTransferListener() { @Override public void fileTransferRequest(FileTransferRequest request) { String fromId = request.getRequestor(); if (fromId != null && !"".equals(fromId)) { String descript = request.getDescription(); IncomingFileTransfer inTransfer = request.accept(); String subName = ".img"; int msgType = IMConfig.MSG_TYPE_IMAGE; if (descript.equals("voice")) { subName = ".arm"; msgType = IMConfig.MSG_TYPE_VOICE; } String fileName = System.currentTimeMillis() + subName; File path; if (Environment.MEDIA_MOUNTED.equals(Environment .getExternalStorageState())) { path = iContext.getExternalFilesDir(fromId.split("@")[0]); } else { path = iContext.getFilesDir(); } String absolutePath = path.getAbsolutePath() + "/" + fileName; File file = new File(absolutePath); try { inTransfer.recieveFile(file); } catch (XMPPException e) { e.printStackTrace(); } if (msgType == IMConfig.MSG_TYPE_IMAGE) { fromId = fromId.split("@")[0]; String friendAlias = getFriendName(fromId); String msgContent = absolutePath; String msgTime = DateTime.getSimpleTime(); addRecentMessageDao(fromId, friendAlias, msgTime, msgContent, ChatMessage.MSG_TYPE_IMG_IN); Log.v(TAG, "img receive success"); } else if (msgType == IMConfig.MSG_TYPE_VOICE) { fromId = fromId.split("@")[0]; String friendAlias = getFriendName(fromId); String msgContent = absolutePath; String msgTime = DateTime.getSimpleTime(); addRecentMessageDao(fromId, friendAlias, msgTime, msgContent, ChatMessage.MSG_TYPE_VOICE_IN); Log.v(TAG, "amr receive success"); } } } }); } @Override public String getFriendName(String userAccount) { if (roster.getEntry(userAccount) == null) { addFriend(userAccount, userAccount, null); } String friendName = roster.getEntry(userAccount).getName(); return friendName; } @Override public boolean addFriend(String userAccount, String alias, String[] groupName) { try { roster.createEntry(userAccount, alias, groupName); } catch (XMPPException e) { e.printStackTrace(); return false; } return true; } @Override public boolean removeFriend(String userAccount) { try { RosterEntry rosterEntry = roster.getEntry(userAccount); roster.removeEntry(rosterEntry); } catch (XMPPException e) { e.printStackTrace(); return false; } return true; } @Override public boolean setAlias(String userAccount, String alias) { RosterEntry rosterEntry = roster.getEntry(userAccount); rosterEntry.setName(alias); return true; } @Override public boolean sendMessage(String userAccount, String message) { try { imConnection.getChatManager().createChat(userAccount, null) .sendMessage(message); } catch (XMPPException e) { e.printStackTrace(); return false; } return true; } @Override public boolean sendFile(String userAccount, String filePath, String type) { try { File file = new File(filePath); OutgoingFileTransfer outTransfer = fileTransferManager .createOutgoingFileTransfer(userAccount); outTransfer.sendFile(file, type); } catch (XMPPException e) { e.printStackTrace(); return false; } return true; } @Override public boolean logout() { if (imConnection.isConnected()) imConnection.disconnect(); return true; }}如有疑问可在下面回复,一一作答,因本人太懒,实在懒得写文字描述了。。。
版权声明:本文为博主原创文章,未经博主允许不得转载。