博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android学习笔记--基于XMPP的即时通讯
阅读量:6317 次
发布时间:2019-06-22

本文共 27680 字,大约阅读时间需要 92 分钟。

一、常见即时通讯实现

socket

openfire+asmack

环信

信鸽

融云

 

二、XMPP优势

1. 开放性

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

 

2.跨平台

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

三、XMPP协议简介  

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

 

数据格式

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

 

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

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

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

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

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

 

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

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

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

例如:

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的即时通讯指令的传递基础,也是一个非常重要的可以被进一步利用的网络基础协议。所以可以说,XMPP用TCP传的是XML流。

 

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

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

这里面封装了所有的方法

 

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

还有一个

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

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

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

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

 

转载于:https://www.cnblogs.com/langfei8818/p/6180724.html

你可能感兴趣的文章
Java 编程的动态性, 第4部分: 用 Javassist 进行类转换--转载
查看>>
完毕port(CompletionPort)具体解释 - 手把手教你玩转网络编程系列之三
查看>>
iOS8 Push Notifications
查看>>
各大名企笔试及面经大全(程序猿必读)
查看>>
Oracle 连接、会话数的查看,修改
查看>>
Oracle 11g password过期被锁定报道 ORA-28000 the account is locked
查看>>
轨磁条简介
查看>>
NSQ部署
查看>>
大厂前端高频面试问题与答案精选
查看>>
如何设计高扩展的在线网页制作平台
查看>>
Git 2.5增加了工作树、改进了三角工作流、性能等诸多方面
查看>>
Swift 5将强制执行内存独占访问
查看>>
中台之上(二):为什么业务架构存在20多年,技术人员还觉得它有点虚?
查看>>
深度揭秘腾讯云低功耗广域物联网LPWAN 技术及应用
查看>>
与Jeff Sutherland谈敏捷领导力
查看>>
More than React(四)HTML也可以静态编译?
查看>>
React Native最佳学习模版- F8 App开源了
查看>>
云服务正在吞噬世界!
查看>>
Web语义化标准解读
查看>>
一份代码构建移动、桌面、Web全平台应用
查看>>