项目要求实现,基于Xmpp的即时通讯,原因嘛,大家都懂的。
用的smack4.17的jar
public class XmppTool { private static XMPPTCPConnectionConfiguration connConfig; private static AbstractXMPPConnection con; private static TaxiConnectionListener taxiConnectionListener;//重连监听 private static OfflineMessageManager offlineManager;//离线消息管理 // 静态加载ReconnectionManager ,重连后正常工作 static { try { Class.forName("org.jivesoftware.smack.ReconnectionManager"); } catch (Exception e) { e.printStackTrace(); } } public static OfflineMessageManager getOffLineMessageManager() { if (offlineManager == null) { offlineManager = new OfflineMessageManager(con); } return offlineManager; } private static void openConnection() { try { XMPPTCPConnectionConfiguration.Builder builder = XMPPTCPConnectionConfiguration.builder(); builder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled); connConfig = builder.setServiceName(Constant.OPENFIRE_SERVICENAME).setHost(Constant.OPENFIRE_HOST).setPort(Constant.OPENFIRE_PORT).setCompressionEnabled(false).setSendPresence(false) .build(); ProviderManager providerManager = new ProviderManager(); con = new XMPPTCPConnection(connConfig); con.connect(); offlineManager = new OfflineMessageManager(con); configure(providerManager); /* final PingManager pingManager = PingManager.getInstanceFor(getConnection()); pingManager.setPingInterval(5); pingManager.registerPingFailedListener(new PingFailedListener() { @Override public void pingFailed() { pingManager.setPingInterval(2); } });*/ } catch (Exception e) { e.printStackTrace(); // TODO: handle exception } } public static TaxiConnectionListener getTaxiConnectionListener() { return taxiConnectionListener; } public static void setTaxiConnectionListener(TaxiConnectionListener taxiConnectionListener) { XmppTool.taxiConnectionListener = taxiConnectionListener; getConnection().addConnectionListener(XmppTool.taxiConnectionListener); } public static AbstractXMPPConnection getConnection() { if (con == null || !con.isConnected()) { openConnection(); } return con; } public static void closeConnection() { if (con != null) { con.removeConnectionListener(XmppTool.taxiConnectionListener); } con.disconnect(); } public static void configure(ProviderManager pm) { pm.addExtensionProvider(DeliveryReceipt.ELEMENT, DeliveryReceipt.NAMESPACE, new DeliveryReceipt.Provider()); pm.addExtensionProvider(DeliveryReceiptRequest.ELEMENT, new DeliveryReceiptRequest().getNamespace(), new DeliveryReceiptRequest.Provider()); // Private Data Storage pm.addIQProvider("query", "jabber:iq:private", new PrivateDataManager.PrivateDataIQProvider()); //pm.addIQProvider(PingProvider,"",new PingProvider()); // 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()); pm.addIQProvider("ping", "urn:xmpp:ping", new PingProvider()); // 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()); // 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()); }
该类主要是用户客户端与服务器建立连接。
public static boolean login(String account, String password, Context context) { try { if (XmppTool.getConnection() == null) return false; /** 登录 */ //SASLAuthentication.supportSASLMechanism("PLAIN"); XmppTool.getConnection().login(account, password); // 设置登录状态:在线 Presence presence = new Presence(Presence.Type.unavailable); XmppTool.getConnection().sendStanza(presence); return true; } catch (Exception e) { e.printStackTrace(); } return false; }登录设置为离线状态这是为了获取离线消息,调用登录方法之后接着调用获取离线消息的方法,获取消息的入口放在服务中。
public static List上面代码是获取离线消息getOffLine(Context context) { Log.i("connectMethod", "getOffLine()"); List msglist = new ArrayList (); // 获取离线消息,线程阻塞 不能Toast try { msglist = XmppTool .getOffLineMessageManager().getMessages(); for (int i = 0; i < msglist.size(); i++) { sendBroadcastMsg(context, msglist.get(i)); } } catch (Exception e) { e.printStackTrace(); } finally { try { // 设置在线 XmppTool.getOffLineMessageManager().deleteMessages(); Presence presence = new Presence(Presence.Type.available); XmppTool.getConnection().sendStanza(presence); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } return msglist; }
/** * 获取在线消息 * * @return */ public static void getOnLine(final Context context) { Log.i("connectMethod", "getOnLine()"); /* DeliveryReceiptManager.getInstanceFor(XmppTool.getConnection()).autoAddDeliveryReceiptRequests();*/ ChatManager cm = ChatManager.getInstanceFor(XmppTool.getConnection()); cm.addChatListener( new ChatManagerListener() { @Override public void chatCreated(Chat chat, boolean createdLocally) { chat.addMessageListener(new ChatMessageListener() { @Override public void processMessage(Chat chat, Message message) { if (!TextUtils.isEmpty(message.getBody())) { sendBroadcastMsg(context, message); } } }); } }); }获取在线消息
/** * 发送消息 * * @param to * @param msg */ public static void sendTalkMsg(String to, Message msg) throws SmackException.NotConnectedException { ChatManager chatManager = ChatManager.getInstanceFor(XmppTool.getConnection()); Chat chat = chatManager.getInstanceFor(XmppTool.getConnection()) .createChat(to, null); /* DeliveryReceiptManager.getInstanceFor(XmppTool.getConnection()).addReceiptReceivedListener(new ReceiptReceivedListener() { public void onReceiptReceived(String fromJid, String toJid, String receiptId, Stanza receipt) { Log.i("connectMethod", receipt.toString()); } });*/ String deliveryReceiptId = DeliveryReceiptRequest.addTo(msg); // DeliveryReceiptRequest.addTo(msg); chat.sendMessage(msg); Log.i("connectMethod", "sendMessage: deliveryReceiptId for this message is: " + deliveryReceiptId); }发送与接收消息代码,基本就是这些,项目中是将表情,图片压缩然后转成字节发送,语音也是转成字节,支持文字语音图片的发送。基本实现聊天功能