android基于Xmpp的即时通讯开发
16lz
2021-01-23
项目要求实现,基于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);}发送与接收消息代码,基本就是这些,项目中是将表情,图片压缩然后转成字节发送,语音也是转成字节,支持文字语音图片的发送。基本实现聊天功能
更多相关文章
- Android Logo消息角标数字提醒
- Android点击通知栏消息,仅打开App,不跳转到具体Activity
- Android中的Handler消息机制
- Android判断app是否打开消息通知并跳转设置
- Android中子线程网络查看器与Handler消息处理器
- Android 与 native C 利用本地socket进行消息传递
- 捕获Android文本输入框的软键盘完成(Done)按键消息
- android TextView 如何实现消息滚动
- android中限制EditText最大输入字节数