Android学习笔记--基于XMPP的即时通讯

本是古典 何须时尚 2021-06-26 16:06 711阅读 0赞

一、常见即时通讯实现

socket

openfire+asmack

环信

信鸽

融云

二、XMPP优势

1. 开放性

XMPP协议是自由、开放、公开的,并且易于了解。而且在客户端、服务器、组件、源码库等方面,都已经各自有多种实现。

2.跨平台

客户端只要基于XMPP协议,不管是什么平台(包括不同的移动终端)都可以互联互通。

三、XMPP协议简介

The Extensible Messaging and Presence Protocol (可扩展通讯和表示协议) XMPPJabber 协议为基础,而 Jabber 是即时通讯中常用的开放式协议。

四、数据格式

XMLXMPP系统架构的核心。它能表述几乎任何一种结构化数据。特别是XMPP利用XML数据流进行客户端一服务器端、服务器端一服务器端的通信。XML数据流一般是由客户端发起至服务端,XML数据流的有效时间直接与用户的在线会话有效时间相关联。

XMPP 的特点是将复杂性从客户端转移到服务器端。这使得客户端编写变得非常容易,更新系统功能也同样变得容易。

XMPP中定义了三个角色:XMPP客户端、XMPP服务器、网关。

客户端:通过 TCP 套接字与XMPP 服务器进行通信

服务器:同时承担了客户端信息记录、连接管理和信息的路由功能

网关:承担着与异构即时通信系统的互联互通(异构系统可以包括SMS(短信),MSN,ICQ等)

五、XMPP协议的地址格式(标志)

每个客户端需要拥有一个地址标识用于定位,XMPP 中称之为 JID (Jabber ID)。地址标识的格式如下

  1. [ node "@" ] domain [ "/" resource ]

例如:

  1. charley@gmail.com/spark

格式与 Email 地址格式类似,但增添了 resource 项(非必需的)。上述例子可以解释为:在 gmail.com 服务器注册的 charley用户,且使用 spark客户端软件登录。资源(resource )只用来识别属于用户的位置或设备等,一个用户可以同时以多种资源与同一个XMPP服务器连接(说白了就是用于支持同一账号的多客户端登录)。

六、协议消息格式

XMPP协议包括3个顶层XML元素:Message、Presence和IQ。

Message用来表示传输的消息,当用户发送一条消息时。就会在流的上下文中插入一个Message元素,中间有用户发送的相关信息;

Presence用来表示用户的状态。当用户改变自己的状态时。就会在数据流的上下文中插入一个Presence元素,用来表示用户现在的状态;

IQ用来表示一种请求,响应机制,从一个实体发送请求,另外一个实体接受请求并响应。

XMPP特点

1.客户端通过TCP/IP协议连接到服务器,然后通过XML传输数据。

2.XMPP的核心部分就是一个在网络上分片断发送XML的流协议。这个流协议是XMPP的即时通讯指令的传递基础,也是一个非常重要的可以被进一步利用的网络基础协议。所以可以说,XMPPTCP传的是XML流。

理论一大堆。。。。接下来贴代码

XmppManager.java

  1. package com.example.xmppdemo.fengzhuang;
  2. import android.util.Log;
  3. import org.jivesoftware.smack.Chat;
  4. import org.jivesoftware.smack.ChatManager;
  5. import org.jivesoftware.smack.ChatManagerListener;
  6. import org.jivesoftware.smack.ConnectionConfiguration;
  7. import org.jivesoftware.smack.MessageListener;
  8. import org.jivesoftware.smack.PacketCollector;
  9. import org.jivesoftware.smack.Roster;
  10. import org.jivesoftware.smack.RosterEntry;
  11. import org.jivesoftware.smack.SmackConfiguration;
  12. import org.jivesoftware.smack.XMPPConnection;
  13. import org.jivesoftware.smack.XMPPException;
  14. import org.jivesoftware.smack.filter.AndFilter;
  15. import org.jivesoftware.smack.filter.PacketFilter;
  16. import org.jivesoftware.smack.filter.PacketIDFilter;
  17. import org.jivesoftware.smack.filter.PacketTypeFilter;
  18. import org.jivesoftware.smack.packet.IQ;
  19. import org.jivesoftware.smack.packet.Message;
  20. import org.jivesoftware.smack.packet.Presence;
  21. import org.jivesoftware.smack.packet.Registration;
  22. import org.jivesoftware.smack.provider.PrivacyProvider;
  23. import org.jivesoftware.smack.provider.ProviderManager;
  24. import org.jivesoftware.smackx.Form;
  25. import org.jivesoftware.smackx.GroupChatInvitation;
  26. import org.jivesoftware.smackx.PrivateDataManager;
  27. import org.jivesoftware.smackx.ReportedData;
  28. import org.jivesoftware.smackx.bytestreams.socks5.provider.BytestreamsProvider;
  29. import org.jivesoftware.smackx.packet.ChatStateExtension;
  30. import org.jivesoftware.smackx.packet.LastActivity;
  31. import org.jivesoftware.smackx.packet.OfflineMessageInfo;
  32. import org.jivesoftware.smackx.packet.OfflineMessageRequest;
  33. import org.jivesoftware.smackx.packet.SharedGroupsInfo;
  34. import org.jivesoftware.smackx.packet.VCard;
  35. import org.jivesoftware.smackx.provider.AdHocCommandDataProvider;
  36. import org.jivesoftware.smackx.provider.DataFormProvider;
  37. import org.jivesoftware.smackx.provider.DelayInformationProvider;
  38. import org.jivesoftware.smackx.provider.DiscoverInfoProvider;
  39. import org.jivesoftware.smackx.provider.DiscoverItemsProvider;
  40. import org.jivesoftware.smackx.provider.MUCAdminProvider;
  41. import org.jivesoftware.smackx.provider.MUCOwnerProvider;
  42. import org.jivesoftware.smackx.provider.MUCUserProvider;
  43. import org.jivesoftware.smackx.provider.MessageEventProvider;
  44. import org.jivesoftware.smackx.provider.MultipleAddressesProvider;
  45. import org.jivesoftware.smackx.provider.RosterExchangeProvider;
  46. import org.jivesoftware.smackx.provider.StreamInitiationProvider;
  47. import org.jivesoftware.smackx.provider.VCardProvider;
  48. import org.jivesoftware.smackx.provider.XHTMLExtensionProvider;
  49. import org.jivesoftware.smackx.search.UserSearch;
  50. import org.jivesoftware.smackx.search.UserSearchManager;
  51. import java.util.ArrayList;
  52. import java.util.Collection;
  53. import java.util.Collections;
  54. import java.util.Iterator;
  55. import java.util.List;
  56. /** * Created by Kelvin on 2016/12/12. */
  57. public class XmppManager {
  58. private static XmppManager xmppManager; //XmppManager的实例
  59. private XmppManager(){ } //私有化构造器
  60. public static XmppManager getInstance(){
  61. if (xmppManager == null){
  62. synchronized (XmppManager.class){
  63. if (xmppManager == null){
  64. xmppManager = new XmppManager();
  65. }
  66. }
  67. }
  68. return xmppManager;
  69. }
  70. //XmppConnection 连接对象
  71. private XMPPConnection xmppConnection;
  72. //将其翻译成中文为"花名册",用来表示一个用户的所有好友清单以及申请加好友的用户清单,
  73. // 为了便于管理,Roster中的用户分组进行管理。
  74. private Roster roster;
  75. //用于接收消息的接口
  76. private XmppManagerCallback xmppManagerCallback;
  77. //Debug标签
  78. private final String TAG="XmppManager";
  79. /** * 打开网络连接 */
  80. private void openConnection(){
  81. //连接对象为空或者还没有认证的时候(isAuthenticated()方法返回值是boolean类型,意思是是否认证)
  82. if (xmppConnection == null || !xmppConnection.isAuthenticated()){
  83. try {
  84. //配置连接,(参数一:服务器ip地址,参数二:端口号,参数三:服务器名字)
  85. ConnectionConfiguration configuration = new ConnectionConfiguration(Constant.SERVER_HOST,
  86. Constant.SERVER_PORT,Constant.SERVER_NAME);
  87. //Xmpp是否可以自动重连(客户端掉线时是否可以重新连接)
  88. configuration.setReconnectionAllowed(true);
  89. //设置安全模式
  90. configuration.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
  91. //特别补充,在设置configuaration的时候对认证的设置,代码如下:
  92. //这个属性默认值是true,设置时得需要与服务器那边统一,如果不一致,就算用户注册成功后,
  93. // 登录时也会返回 server-unavailable(503)错误,我们用的是ejabberd服务器,默认设置SASL认证开启,
  94. // 所以开始我设置为false,怎么都无法登录,最后注释这句代码,成功登录:)
  95. //相当于一个权限
  96. configuration.setSASLAuthenticationEnabled(false);
  97. // 状态设为离线,为了取离线消息
  98. configuration.setSendPresence(true);
  99. // 配置各种Provider,如果不配置,则会无法解析数据
  100. configureConnection(ProviderManager.getInstance());
  101. xmppConnection = new XMPPConnection(configuration);
  102. //打开连接
  103. xmppConnection.connect();
  104. } catch (XMPPException e) {
  105. e.printStackTrace();
  106. }
  107. }
  108. }
  109. /** * 配置连接 * @param pm */
  110. public void configureConnection(ProviderManager pm) {
  111. // Private Data Storage
  112. pm.addIQProvider("query", "jabber:iq:private", new PrivateDataManager.PrivateDataIQProvider());
  113. // Time
  114. try {
  115. pm.addIQProvider("query", "jabber:iq:time", Class.forName("org.jivesoftware.smackx.packet.Time"));
  116. } catch (ClassNotFoundException e) {
  117. Log.w("TestClient", "Can't load class for org.jivesoftware.smackx.packet.Time");
  118. }
  119. // Roster Exchange
  120. pm.addExtensionProvider("x", "jabber:x:roster", new RosterExchangeProvider());
  121. // Message Events
  122. pm.addExtensionProvider("x", "jabber:x:event", new MessageEventProvider());
  123. // Chat State
  124. pm.addExtensionProvider("active", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
  125. pm.addExtensionProvider("composing", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
  126. pm.addExtensionProvider("paused", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
  127. pm.addExtensionProvider("inactive", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
  128. pm.addExtensionProvider("gone", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
  129. // XHTML
  130. pm.addExtensionProvider("html", "http://jabber.org/protocol/xhtml-im", new XHTMLExtensionProvider());
  131. // Group Chat Invitations
  132. pm.addExtensionProvider("x", "jabber:x:conference", new GroupChatInvitation.Provider());
  133. // Service Discovery # Items
  134. pm.addIQProvider("query", "http://jabber.org/protocol/disco#items", new DiscoverItemsProvider());
  135. // Service Discovery # Info
  136. pm.addIQProvider("query", "http://jabber.org/protocol/disco#info", new DiscoverInfoProvider());
  137. // Data Forms
  138. pm.addExtensionProvider("x", "jabber:x:data", new DataFormProvider());
  139. // MUC User
  140. pm.addExtensionProvider("x", "http://jabber.org/protocol/muc#user", new MUCUserProvider());
  141. // MUC Admin
  142. pm.addIQProvider("query", "http://jabber.org/protocol/muc#admin", new MUCAdminProvider());
  143. // MUC Owner
  144. pm.addIQProvider("query", "http://jabber.org/protocol/muc#owner", new MUCOwnerProvider());
  145. // Delayed Delivery
  146. pm.addExtensionProvider("x", "jabber:x:delay", new DelayInformationProvider());
  147. // Version
  148. try {
  149. pm.addIQProvider("query", "jabber:iq:version", Class.forName("org.jivesoftware.smackx.packet.Version"));
  150. } catch (ClassNotFoundException e) {
  151. // Not sure what's happening here.
  152. }
  153. // VCard
  154. pm.addIQProvider("vCard", "vcard-temp", new VCardProvider());
  155. // Offline Message Requests
  156. pm.addIQProvider("offline", "http://jabber.org/protocol/offline", new OfflineMessageRequest.Provider());
  157. // Offline Message Indicator
  158. pm.addExtensionProvider("offline", "http://jabber.org/protocol/offline", new OfflineMessageInfo.Provider());
  159. // Last Activity
  160. pm.addIQProvider("query", "jabber:iq:last", new LastActivity.Provider());
  161. // User Search
  162. pm.addIQProvider("query", "jabber:iq:search", new UserSearch.Provider());
  163. // SharedGroupsInfo
  164. pm.addIQProvider("sharedgroup", "http://www.jivesoftware.org/protocol/sharedgroup",
  165. new SharedGroupsInfo.Provider());
  166. // JEP-33: Extended Stanza Addressing
  167. pm.addExtensionProvider("addresses", "http://jabber.org/protocol/address", new MultipleAddressesProvider());
  168. // FileTransfer
  169. pm.addIQProvider("si", "http://jabber.org/protocol/si", new StreamInitiationProvider());
  170. pm.addIQProvider("query", "http://jabber.org/protocol/bytestreams", new BytestreamsProvider());
  171. // Privacy
  172. pm.addIQProvider("query", "jabber:iq:privacy", new PrivacyProvider());
  173. pm.addIQProvider("command", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider());
  174. pm.addExtensionProvider("malformed-action", "http://jabber.org/protocol/commands",
  175. new AdHocCommandDataProvider.MalformedActionError());
  176. pm.addExtensionProvider("bad-locale", "http://jabber.org/protocol/commands",
  177. new AdHocCommandDataProvider.BadLocaleError());
  178. pm.addExtensionProvider("bad-payload", "http://jabber.org/protocol/commands",
  179. new AdHocCommandDataProvider.BadPayloadError());
  180. pm.addExtensionProvider("bad-sessionid", "http://jabber.org/protocol/commands",
  181. new AdHocCommandDataProvider.BadSessionIDError());
  182. pm.addExtensionProvider("session-expired", "http://jabber.org/protocol/commands",
  183. new AdHocCommandDataProvider.SessionExpiredError());
  184. }
  185. /** * 获取链接 * @return */
  186. public XMPPConnection getConnection(){
  187. if (xmppConnection == null){
  188. openConnection();
  189. }
  190. return xmppConnection;
  191. }
  192. /** * 关闭链接 */
  193. public void colseConnection(){
  194. if (xmppConnection != null && xmppConnection.isConnected()){
  195. xmppConnection.disconnect();
  196. xmppConnection = null;
  197. }
  198. }
  199. /** * 登陆的方法 * @param account 账号 * @param psw 密码 * @return */
  200. public boolean login(String account,String psw){
  201. //判断连接是否存在
  202. if (getConnection() == null){
  203. return false;
  204. }
  205. if (!getConnection().isAuthenticated() && getConnection().isConnected()){
  206. try {
  207. //登陆
  208. getConnection().login(account,psw);
  209. //登陆之后更改用户状态
  210. Presence presence = new Presence(Presence.Type.available);
  211. //设置用户在线
  212. presence.setMode(Presence.Mode.available);
  213. //向服务器发送状态
  214. getConnection().sendPacket(presence);
  215. //接收消息监听
  216. ChatManager chatManager = getConnection().getChatManager();
  217. chatManager.addChatListener(chatManagerListener);
  218. return true;
  219. } catch (XMPPException e) {
  220. e.printStackTrace();
  221. return false;
  222. }
  223. }
  224. return false;
  225. }
  226. /** * 聊天管理监听器 */
  227. private ChatManagerListener chatManagerListener = new ChatManagerListener(){
  228. @Override
  229. public void chatCreated(Chat chat, boolean b) {
  230. chat.addMessageListener(new MessageListener() {
  231. @Override
  232. public void processMessage(Chat chat, Message message) {
  233. //当消息内容为空时,直接反悔
  234. if (TVUtil.isEmpty(message.getBody())){
  235. return;
  236. }
  237. //当消息内容不可空时,通过接口回调的把消息内容传出去
  238. if (xmppManagerCallback != null){
  239. xmppManagerCallback.receiveMsg(message);
  240. }
  241. }
  242. });
  243. }
  244. };
  245. /** * 注册用户 * 表示的是Info/Query(信息与查询),它为XMPP通信提供请求与响应机制。它与HTTP * 协议的基本工作原理非常相似,允许获取和设置查询,与HTTP 的GET 和POST 动作类似。 * @return */
  246. public IQ registered(String account, String psw){
  247. if (getConnection() == null){
  248. return null;
  249. }
  250. //设置注册所需要的信息
  251. Registration registration = new Registration();
  252. registration.setType(IQ.Type.SET);
  253. registration.setTo(getConnection().getServiceName());
  254. registration.setUsername(account);
  255. registration.setPassword(psw);
  256. //PacketFilter:包过滤类,过滤一些不用的包
  257. PacketFilter filter = new AndFilter(new PacketIDFilter(registration.getPacketID()), new PacketTypeFilter(IQ.class));
  258. PacketCollector collector = getConnection().createPacketCollector(filter);
  259. // 向服务器端,发送注册Packet包,注意其中Registration是Packet的子类
  260. getConnection().sendPacket(registration);
  261. IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
  262. collector.cancel(); //停止请求result
  263. return result;
  264. }
  265. /** * 退出登陆 */
  266. public void outLogin(){
  267. if (getConnection() == null){
  268. return;
  269. }
  270. //设置退出状态
  271. Presence presence = new Presence(Presence.Type.unavailable);
  272. //发送请求
  273. getConnection().sendPacket(presence);
  274. //关闭连接
  275. colseConnection();
  276. }
  277. /** * 获取用户信息 * @param user * @return */
  278. public VCard getUserInfo(String user){
  279. VCard vCard = null;
  280. try {
  281. vCard = new VCard();
  282. // 加入这句代码,解决No VCard for
  283. ProviderManager.getInstance().addIQProvider("vCard", "vcard-temp", new VCardProvider());
  284. if (user == null){
  285. vCard.load(getConnection());
  286. }else{
  287. vCard.load(getConnection(), user + "@" + Constant.SERVER_NAME);
  288. }
  289. } catch (XMPPException e) {
  290. e.printStackTrace();
  291. }
  292. return vCard;
  293. }
  294. /** * 获取xmpp好友列表 * 注意:这里的User是在Xmpp包下的User */
  295. public List<User> getFriendList() {
  296. // Roster:花名册
  297. if (roster == null) {
  298. roster = getConnection().getRoster();
  299. }
  300. List<User> userList = new ArrayList<User>();
  301. Collection<RosterEntry> entries = roster.getEntries();
  302. for(RosterEntry entry : entries){
  303. userList.add(new User(getUsername(entry.getUser()),entry.getType()));
  304. }
  305. Collections.sort(userList,new PingyinComparator());
  306. return userList;
  307. }
  308. /** * 通过jid获得username * @param fullUsername * @return */
  309. public static String getUsername(String fullUsername){
  310. return fullUsername.split("@")[0];
  311. }
  312. /** * 搜索用户 * @param userName * @return * @throws XMPPException */
  313. public List<String> searchUser(String userName) {
  314. if (getConnection() == null){
  315. return null;
  316. }
  317. List<String> userList = new ArrayList<>();
  318. try {
  319. UserSearchManager search = new UserSearchManager(getConnection());
  320. Form searchForm = search.getSearchForm("search."+ getConnection().getServiceName());
  321. Form answerForm = searchForm.createAnswerForm();
  322. answerForm.setAnswer("Username", true);
  323. answerForm.setAnswer("search", userName.trim());
  324. ReportedData data = search.getSearchResults(answerForm,"search." + xmppConnection.getServiceName());
  325. Iterator<ReportedData.Row> it = data.getRows();
  326. ReportedData.Row row = null;
  327. while (it.hasNext()) {
  328. row = it.next();
  329. userList.add(row.getValues("Username").next().toString());
  330. }
  331. } catch (XMPPException e) {
  332. e.printStackTrace();
  333. }
  334. return userList;
  335. }
  336. /** * 添加好友(无分组) * @param userName * @return */
  337. public boolean addFriend(String userName) {
  338. if (getConnection() == null)
  339. return false;
  340. try {
  341. getConnection().getRoster().createEntry(getFullUsername(userName), getFullUsername(userName), null);
  342. return true;
  343. } catch (Exception e) {
  344. e.printStackTrace();
  345. return false;
  346. }
  347. }
  348. /** * 通过username获得jid * @param username * @return */
  349. public static String getFullUsername(String username){
  350. return username + "@" + Constant.SERVER_NAME;
  351. }
  352. /** * 创建聊天 * @param toUser * @return */
  353. public Chat createChat(String toUser){
  354. ChatManager chatManager = getConnection().getChatManager();
  355. Chat newchat = chatManager.createChat(toUser + "@"+ Constant.SERVER_NAME, null);
  356. return newchat;
  357. }
  358. /** * 发送文本消息 * @param message */
  359. public void sendMsg(Chat chat, String message) {
  360. try {
  361. chat.sendMessage(message);
  362. } catch (Exception e) {
  363. e.printStackTrace();
  364. }
  365. }
  366. /** * 接口回调 */
  367. public interface XmppManagerCallback {
  368. //接收消息回调函数
  369. void receiveMsg(Message message);
  370. }
  371. /** * 设置接口的方法 * @param xmppManagerCallback 接口对象 */
  372. public void setXmppManagerCallback(XmppManagerCallback xmppManagerCallback) {
  373. this.xmppManagerCallback = xmppManagerCallback;
  374. }
  375. }

这里面封装了所有的方法

ChatMsg.java

  1. package com.example.xmppdemo.fengzhuang;
  2. import android.os.Parcel;
  3. import android.os.Parcelable;
  4. /** * * 描述(请用一句话描述这个内容) */
  5. public class ChatMsg implements Parcelable {
  6. private String sender; // 发送者
  7. private String body; // 发送的消息
  8. public String getSender() {
  9. return sender;
  10. }
  11. public void setSender(String sender) {
  12. this.sender = sender;
  13. }
  14. public String getBody() {
  15. return body;
  16. }
  17. public void setBody(String body) {
  18. this.body = body;
  19. }
  20. public static final Creator<ChatMsg> CREATOR = new Creator<ChatMsg>() {
  21. @Override
  22. public ChatMsg createFromParcel(Parcel in) {
  23. ChatMsg chatMsg = new ChatMsg();
  24. chatMsg.sender = in.readString();
  25. chatMsg.body = in.readString();
  26. return chatMsg;
  27. }
  28. @Override
  29. public ChatMsg[] newArray(int size) {
  30. return null;
  31. }
  32. };
  33. @Override
  34. public int describeContents() {
  35. return 0;
  36. }
  37. @Override
  38. public void writeToParcel(Parcel parcel, int i) {
  39. parcel.writeString(sender);
  40. parcel.writeString(body);
  41. }
  42. }

还有一个

ChatService.java

  1. package com.example.xmppdemo.service;
  2. import android.app.Activity;
  3. import android.app.Notification;
  4. import android.app.NotificationManager;
  5. import android.app.PendingIntent;
  6. import android.app.Service;
  7. import android.content.BroadcastReceiver;
  8. import android.content.Context;
  9. import android.content.Intent;
  10. import android.content.IntentFilter;
  11. import android.os.IBinder;
  12. import android.support.annotation.Nullable;
  13. import com.example.xmppdemo.ChatActivity;
  14. import com.example.xmppdemo.R;
  15. import com.example.xmppdemo.fengzhuang.ChatMsg;
  16. import com.example.xmppdemo.fengzhuang.Constant;
  17. import com.example.xmppdemo.fengzhuang.XmppManager;
  18. import org.jivesoftware.smack.XMPPException;
  19. import org.jivesoftware.smack.packet.Message;
  20. import org.jivesoftware.smackx.OfflineMessageManager;
  21. import java.util.ArrayList;
  22. import java.util.Iterator;
  23. /** 31 * 描述(请用一句话描述这个内容) */
  24. public class ChatService extends Service implements XmppManager.XmppManagerCallback {
  25. //接收到的消息集合,包括两种消息: 1,不在对话框界面的消息 2,离线消息
  26. private ArrayList<ChatMsg> messageList = new ArrayList<>();
  27. private MesageBroadcastReceiver mesageReceiver;
  28. @Override
  29. public void onCreate() {
  30. XmppManager.getInstance().setXmppManagerCallback(this);
  31. //注册消息接收广播
  32. IntentFilter filter = new IntentFilter(Constant.INTENT_ACTION_MESSAGE_RECEIVE);
  33. mesageReceiver = new MesageBroadcastReceiver();
  34. registerReceiver(mesageReceiver, filter);
  35. }
  36. @Nullable
  37. @Override
  38. public IBinder onBind(Intent intent) {
  39. return null;
  40. }
  41. @Override
  42. public void receiveMsg(Message message) {
  43. ChatMsg chatMsg = new ChatMsg();
  44. chatMsg.setSender(message.getFrom());
  45. chatMsg.setBody(message.getBody());
  46. sendReceiverMsgBroadCast(chatMsg);
  47. }
  48. /** * 发送广播的方法 * @param */
  49. private void sendReceiverMsgBroadCast(ChatMsg chatMsg){
  50. Intent intent = new Intent();
  51. intent.setAction(Constant.INTENT_ACTION_MESSAGE_RECEIVE);
  52. intent.putExtra("message", chatMsg);
  53. /** * MesageBroadcastReceiver指定为最后的接受者,Activity.RESULT_CANCELED指定初始的结果码, * 如果ChatActivity中的广播接收者处理了这条广播,则结果码会在ChatActivity中被更改为Activity.RESULT_OK, * 反之,ChatActivity中的广播接收者没有处理,则结果码仍然为Activity.RESULT_CANCELED */
  54. sendOrderedBroadcast(intent,null,mesageReceiver,null, Activity.RESULT_CANCELED,null,null);
  55. }
  56. /** * 消息广播 */
  57. private class MesageBroadcastReceiver extends BroadcastReceiver{
  58. @Override
  59. public void onReceive(Context context, Intent intent) {
  60. ChatMsg chatMsg = intent.getParcelableExtra("message");
  61. int resultCode = getResultCode();
  62. if (isOrderedBroadcast()){ //判断是否有下一个广播,true为是 false为无
  63. if (resultCode != Activity.RESULT_OK){
  64. showMsgNotice(chatMsg);
  65. }
  66. }
  67. }
  68. }
  69. /** * 显示消息通知 * @param chatMsg 消息类 */
  70. private void showMsgNotice(ChatMsg chatMsg){
  71. messageList.add(chatMsg); //把消息实体加入到集合中
  72. //获取通知服务
  73. NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
  74. //取消所有
  75. nm.cancelAll();
  76. //创建消息
  77. /* Notification notification = new Notification(R.drawable.ic_launcher ,"您有"+messageList.size()+"条新消息", System.currentTimeMillis()); notification.flags = Notification.FLAG_AUTO_CANCEL; notification.sound= Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.ms); Intent intent = new Intent(this, ChatActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra("from", "notification"); intent.putParcelableArrayListExtra("messageList", messageList); PendingIntent contentIntent = PendingIntent.getActivity(this, R.string.app_name, intent, PendingIntent.FLAG_UPDATE_CURRENT); notification.setLatestEventInfo(this, chatMsg.getSender().split("@")[0], chatMsg.getBody(), contentIntent); nm.notify(0, notification);*/
  78. Notification.Builder builder = new Notification.Builder(this);
  79. builder.setContentText("微信通知"); //设置通知的标题
  80. builder.setSmallIcon(R.drawable.search_icon); //设置通知的小图标
  81. builder.setContentText("您有"+messageList.size()+"条新消息"); //写入通知内容
  82. // builder.setSound(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.ms));
  83. Intent intent = new Intent(this, ChatActivity.class);
  84. intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
  85. intent.putExtra("from", "notification");
  86. intent.putParcelableArrayListExtra("messageList", messageList);
  87. PendingIntent contentIntent = PendingIntent.getActivity(this, R.string.app_name, intent, PendingIntent.FLAG_UPDATE_CURRENT);
  88. builder.setContentIntent(contentIntent);
  89. //获得通知
  90. Notification notification = builder.getNotification();
  91. nm.notify(0, notification);
  92. }
  93. /** * 获取离线消息 */
  94. public void getOfflineMessage() {
  95. OfflineMessageManager offlineMessageManager = new OfflineMessageManager(XmppManager.getInstance().getConnection());
  96. try {
  97. Iterator<Message> it = offlineMessageManager.getMessages();
  98. while (it.hasNext()) {
  99. Message message = it.next();
  100. ChatMsg chatMsg = new ChatMsg();
  101. chatMsg.setSender(message.getFrom());
  102. chatMsg.setBody(message.getBody());
  103. sendReceiverMsgBroadCast(chatMsg);
  104. }
  105. offlineMessageManager.deleteMessages();
  106. } catch (XMPPException e) {
  107. e.printStackTrace();
  108. }
  109. }
  110. @Override
  111. public void onDestroy() {
  112. super.onDestroy();
  113. XmppManager.getInstance().colseConnection();
  114. unregisterReceiver(mesageReceiver);
  115. }
  116. }

基本重要的就这么多,代码附上,

链接:http://pan.baidu.com/s/1hs1Dg3M 密码:s57b

可能说的不是很清楚,但是代码里面都有

能看到的代码不是自己的,自己写出来的才是自己的

发表评论

表情:
评论列表 (有 0 条评论,711人围观)

还没有评论,来说两句吧...

相关阅读