功能实现:注册,登录,单聊表情,文本,图片,语音的发送接收,添加好友,删除好友,查找好友,修改密码,消息提醒设置,获取离线消息等功能


1.前期准备

1.下载opnefire软件:https://www.igniterealtime.org/downloads/index.jsp

2.下载一款数据库软件:mysql

4.在AS中添加smack相关依赖包:

    compile 'org.igniterealtime.smack:smack-android-extensions:4.1.4'compile 'org.igniterealtime.smack:smack-tcp:4.1.4'compile 'org.igniterealtime.smack:smack-im:4.1.4'compile 'org.igniterealtime.smack:smack-extensions:4.1.4'compile 'com.rockerhieu.emojicon:library:1.3.3'

5.核心代码块:


XmppConnection 工具类 

   1 import android.content.Context;
   2 import android.database.Cursor;
   3 import android.os.Environment;
   4 import android.text.TextUtils;
   5 import android.util.Log;
   6
   7 import org.jivesoftware.smack.AbstractXMPPConnection;
   8 import org.jivesoftware.smack.ConnectionConfiguration;
   9 import org.jivesoftware.smack.MessageListener;
  10 import org.jivesoftware.smack.SmackConfiguration;
  11 import org.jivesoftware.smack.SmackException;
  12 import org.jivesoftware.smack.XMPPException;
  13 import org.jivesoftware.smack.chat.Chat;
  14 import org.jivesoftware.smack.chat.ChatManager;
  15 import org.jivesoftware.smack.chat.ChatMessageListener;
  16 import org.jivesoftware.smack.packet.Message;
  17 import org.jivesoftware.smack.packet.Presence;
  18 import org.jivesoftware.smack.provider.ProviderManager;
  19 import org.jivesoftware.smack.roster.Roster;
  20 import org.jivesoftware.smack.roster.RosterEntry;
  21 import org.jivesoftware.smack.roster.RosterGroup;
  22 import org.jivesoftware.smack.tcp.XMPPTCPConnection;
  23 import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
  24 import org.jivesoftware.smackx.address.provider.MultipleAddressesProvider;
  25 import org.jivesoftware.smackx.bytestreams.ibb.provider.CloseIQProvider;
  26 import org.jivesoftware.smackx.bytestreams.ibb.provider.OpenIQProvider;
  27 import org.jivesoftware.smackx.bytestreams.socks5.provider.BytestreamsProvider;
  28 import org.jivesoftware.smackx.chatstates.packet.ChatStateExtension;
  29 import org.jivesoftware.smackx.commands.provider.AdHocCommandDataProvider;
  30 import org.jivesoftware.smackx.delay.provider.DelayInformationProvider;
  31 import org.jivesoftware.smackx.disco.provider.DiscoverInfoProvider;
  32 import org.jivesoftware.smackx.disco.provider.DiscoverItemsProvider;
  33 import org.jivesoftware.smackx.filetransfer.FileTransferListener;
  34 import org.jivesoftware.smackx.filetransfer.FileTransferManager;
  35 import org.jivesoftware.smackx.filetransfer.FileTransferRequest;
  36 import org.jivesoftware.smackx.filetransfer.IncomingFileTransfer;
  37 import org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer;
  38 import org.jivesoftware.smackx.iqlast.packet.LastActivity;
  39 import org.jivesoftware.smackx.iqprivate.PrivateDataManager;
  40 import org.jivesoftware.smackx.iqregister.AccountManager;
  41 import org.jivesoftware.smackx.muc.DiscussionHistory;
  42 import org.jivesoftware.smackx.muc.HostedRoom;
  43 import org.jivesoftware.smackx.muc.MultiUserChat;
  44 import org.jivesoftware.smackx.muc.MultiUserChatManager;
  45 import org.jivesoftware.smackx.muc.packet.GroupChatInvitation;
  46 import org.jivesoftware.smackx.muc.provider.MUCAdminProvider;
  47 import org.jivesoftware.smackx.muc.provider.MUCOwnerProvider;
  48 import org.jivesoftware.smackx.muc.provider.MUCUserProvider;
  49 import org.jivesoftware.smackx.offline.OfflineMessageManager;
  50 import org.jivesoftware.smackx.offline.packet.OfflineMessageInfo;
  51 import org.jivesoftware.smackx.offline.packet.OfflineMessageRequest;
  52 import org.jivesoftware.smackx.privacy.provider.PrivacyProvider;
  53 import org.jivesoftware.smackx.search.ReportedData;
  54 import org.jivesoftware.smackx.search.UserSearch;
  55 import org.jivesoftware.smackx.search.UserSearchManager;
  56 import org.jivesoftware.smackx.sharedgroups.packet.SharedGroupsInfo;
  57 import org.jivesoftware.smackx.si.provider.StreamInitiationProvider;
  58 import org.jivesoftware.smackx.vcardtemp.provider.VCardProvider;
  59 import org.jivesoftware.smackx.xdata.Form;
  60 import org.jivesoftware.smackx.xdata.FormField;
  61 import org.jivesoftware.smackx.xdata.provider.DataFormProvider;
  62 import org.jivesoftware.smackx.xhtmlim.provider.XHTMLExtensionProvider;
  63
  64 import java.io.BufferedInputStream;
  65 import java.io.BufferedReader;
  66 import java.io.File;
  67 import java.io.FileInputStream;
  68 import java.io.IOException;
  69 import java.io.InputStreamReader;
  70 import java.net.URL;
  71 import java.net.URLConnection;
  72 import java.util.ArrayList;
  73 import java.util.Collection;
  74 import java.util.Date;
  75 import java.util.HashMap;
  76 import java.util.Iterator;
  77 import java.util.List;
  78 import java.util.Map;
  79 import java.util.Set;
  80
  81 import cnpc.fcyt.fcydyy.util.LoggerUtil;
  82 import cnpc.fcyt.fcydyy.xmpp.bean.XmppChat;
  83 import cnpc.fcyt.fcydyy.xmpp.bean.XmppMessage;
  84 import cnpc.fcyt.fcydyy.xmpp.bean.XmppUser;
  85 import cnpc.fcyt.fcydyy.xmpp.dao.FriendChatDao;
  86 import cnpc.fcyt.fcydyy.xmpp.dao.MessageDao;
  87 import cnpc.fcyt.fcydyy.xmpp.util.TimeUtil;
  88 import cnpc.fcyt.fcydyy.xmpp.util.UserConstants;
  89
  90 /**
  91  * XmppConnection 工具类
  92  */
  93
  94 public class XmppConnection {
  95     private int SERVER_PORT = 5222;
  96     private String SERVER_HOST = "192.168.0.195";
  97     private String SERVER_NAME = "192.168.0.195";
  98     public AbstractXMPPConnection connection = null;
  99     private static XmppConnection xmppConnection = new XmppConnection();
 100     private XMConnectionListener connectionListener;
 101
 102     /**
 103      * 单例模式
 104      *
 105      * @return XmppConnection
 106      */
 107     public synchronized static XmppConnection getInstance() {
 108         configure(new ProviderManager());
 109         return xmppConnection;
 110     }
 111
 112     /**
 113      * 创建连接
 114      */
 115     public AbstractXMPPConnection getConnection() {
 116
 117         if (connection == null) {
 118             // 开线程打开连接,避免在主线程里面执行HTTP请求
 119             // Caused by: android.os.NetworkOnMainThreadException
 120             new Thread(new Runnable() {
 121                 @Override
 122                 public void run() {
 123                     openConnection();
 124                 }
 125             }).start();
 126         }
 127         return connection;
 128     }
 129
 130     public void setConnectionToNull() {
 131         connection = null;
 132     }
 133
 134     /**
 135      * 判断是否已连接
 136      */
 137     public boolean checkConnection() {
 138         return null != connection && connection.isConnected();
 139     }
 140
 141     /**
 142      * 打开连接
 143      */
 144     public boolean openConnection() {
 145         try {
 146             if (null == connection || !connection.isAuthenticated()) {
 147                 SmackConfiguration.DEBUG = true;
 148                 XMPPTCPConnectionConfiguration.Builder config = XMPPTCPConnectionConfiguration.builder();
 149                 //设置openfire主机IP
 150                 config.setHost(SERVER_HOST);
 151                 //设置openfire服务器名称
 152                 config.setServiceName(SERVER_NAME);
 153                 //设置端口号:默认5222
 154                 config.setPort(SERVER_PORT);
 155                 //禁用SSL连接
 156                 config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled).setCompressionEnabled(false);
 157                 //设置Debug
 158                 config.setDebuggerEnabled(true);
 159                 //设置离线状态
 160                 config.setSendPresence(false);
 161                 //设置开启压缩,可以节省流量
 162                 config.setCompressionEnabled(true);
 163
 164                 //需要经过同意才可以添加好友
 165                 Roster.setDefaultSubscriptionMode(Roster.SubscriptionMode.accept_all);
 166
 167                 // 将相应机制隐掉
 168                 //SASLAuthentication.blacklistSASLMechanism("SCRAM-SHA-1");
 169                 //SASLAuthentication.blacklistSASLMechanism("DIGEST-MD5");
 170
 171                 connection = new XMPPTCPConnection(config.build());
 172                 connection.connect();// 连接到服务器
 173
 174                 return true;
 175             }
 176         } catch (Exception xe) {
 177             xe.printStackTrace();
 178             connection = null;
 179         }
 180         return false;
 181     }
 182
 183     /**
 184      * 关闭连接
 185      */
 186     public void closeConnection() {
 187         if (connection != null) {
 188             // 移除连接监听
 189             connection.removeConnectionListener(connectionListener);
 190             if (connection.isConnected())
 191                 connection.disconnect();
 192             connection = null;
 193         }
 194
 195         Log.i("XmppConnection", "关闭连接");
 196     }
 197
 198     /**
 199      * 删除好友
 200      *
 201      * @param
 202      */
 203     public boolean deleteRosterEntry(RosterEntry rosterEntry) {
 204         try {
 205             Roster.getInstanceFor(connection).removeEntry(rosterEntry);
 206             return true;
 207         } catch (Exception e) {
 208             e.printStackTrace();
 209             return false;
 210         }
 211     }
 212
 213     /**
 214      * 判断连接是否通过了身份验证
 215      * 即是否已登录
 216      *
 217      * @return
 218      */
 219     public boolean isAuthenticated() {
 220         return connection != null && connection.isConnected() && connection.isAuthenticated();
 221     }
 222
 223     /**
 224      * 添加好友 无分组
 225      *
 226      * @param userName userName
 227      * @param name     name
 228      * @return boolean
 229      */
 230     public boolean addUser(String userName, String name) {
 231         if (getConnection() == null)
 232             return false;
 233         try {
 234
 235             Roster.getInstanceFor(connection).createEntry(userName, name, null);
 236
 237             return true;
 238         } catch (Exception e) {
 239             e.printStackTrace();
 240             return false;
 241         }
 242     }
 243
 244     /**
 245      * 获取账号的全部信息
 246      */
 247     public void getAccountAttributes() {
 248         try {
 249
 250             Set<String> accountAttributes = AccountManager.getInstance(connection).getAccountAttributes();
 251             Iterator<String> iterator = accountAttributes.iterator();
 252             while (iterator.hasNext()) {
 253                 String trim = iterator.next().toString().trim();
 254                 Log.e("Account", "获取账号信息成功===" + trim);
 255             }
 256         } catch (SmackException.NoResponseException e) {
 257             e.printStackTrace();
 258             Log.e("Account", "连接服务器失败");
 259         } catch (XMPPException.XMPPErrorException e) {
 260             e.printStackTrace();
 261             Log.e("Account", "该账户已存在");
 262         } catch (SmackException.NotConnectedException e) {
 263             e.printStackTrace();
 264             Log.e("Account", "服务器连接失败");
 265         }
 266     }
 267
 268     /**
 269      * 登录
 270      *
 271      * @param account  登录帐号
 272      * @param password 登录密码
 273      * @return true登录成功
 274      */
 275     public boolean login(String account, String password) {
 276         try {
 277             if (getConnection() == null)
 278                 return false;
 279
 280             getConnection().login(account, password);
 281
 282             // 更改在线状态
 283 //            setPresence(0);
 284
 285             // 添加连接监听
 286             connectionListener = new XMConnectionListener(account, password);
 287             getConnection().addConnectionListener(connectionListener);
 288             receivedFile();
 289             return true;
 290         } catch (Exception xe) {
 291             xe.printStackTrace();
 292         }
 293         return false;
 294     }
 295
 296
 297     /**
 298      * 获取用户离线在线状态  1 在线  2 离线
 299      */
 300     public int getStatus(RosterEntry entry) {
 301         Roster roster = Roster.getInstanceFor(connection);
 302         Presence presence = roster.getPresence(entry.getUser() + UserConstants.chatDoMain);
 303
 304         LoggerUtil.systemOut(entry.getUser() + "用户名");
 305         LoggerUtil.systemOut(presence.getType().name() + "获取到的 类型状态");
 306         LoggerUtil.systemOut(presence.getType().toString() + "获取到的 类型状态");
 307         if (presence.getType() == Presence.Type.available) {
 308             return 1;//在线
 309         }
 310         return 2;//离线
 311     }
 312
 313     /**
 314      * 更改用户状态
 315      */
 316     public void setPresence(int code) {
 317         org.jivesoftware.smack.XMPPConnection con = getConnection();
 318         if (con == null)
 319             return;
 320         Presence presence;
 321         try {
 322             switch (code) {
 323                 case 0:
 324                     presence = new Presence(Presence.Type.available);
 325                     con.sendStanza(presence);
 326                     Log.v("state", "设置在线");
 327                     break;
 328                 case 1:
 329                     presence = new Presence(Presence.Type.available);
 330                     presence.setMode(Presence.Mode.chat);
 331                     con.sendStanza(presence);
 332                     Log.v("state", "设置Q我吧");
 333                     break;
 334                 case 2:
 335                     presence = new Presence(Presence.Type.available);
 336                     presence.setMode(Presence.Mode.dnd);
 337                     con.sendStanza(presence);
 338                     Log.v("state", "设置忙碌");
 339                     break;
 340                 case 3:
 341                     presence = new Presence(Presence.Type.available);
 342                     presence.setMode(Presence.Mode.away);
 343                     con.sendStanza(presence);
 344                     Log.v("state", "设置离开");
 345                     break;
 346                 case 4:
 347 //                    Roster roster = con.getRoster();
 348 //                    Collection<RosterEntry> entries = roster.getEntries();
 349 //                    for (RosterEntry entry : entries) {
 350 //                        presence = new Presence(Presence.Type.unavailable);
 351 //                        presence.setPacketID(Packet.ID_NOT_AVAILABLE);
 352 //                        presence.setFrom(con.getUser());
 353 //                        presence.setTo(entry.getUser());
 354 //                        con.sendPacket(presence);
 355 //                        Log.v("state", presence.toXML());
 356 //                    }
 357 //                    // 向同一用户的其他客户端发送隐身状态
 358 //                    presence = new Presence(Presence.Type.unavailable);
 359 //                    presence.setPacketID(Packet.ID_NOT_AVAILABLE);
 360 //                    presence.setFrom(con.getUser());
 361 //                    presence.setTo(StringUtils.parseBareAddress(con.getUser()));
 362 //                    con.sendStanza(presence);
 363 //                    Log.v("state", "设置隐身");
 364 //                    break;
 365                 case 5:
 366                     presence = new Presence(Presence.Type.unavailable);
 367                     con.sendStanza(presence);
 368                     Log.v("state", "设置离线");
 369                     break;
 370                 default:
 371                     break;
 372             }
 373         } catch (Exception e) {
 374             e.printStackTrace();
 375         }
 376     }
 377
 378     /**
 379      * 获取所有组
 380      *
 381      * @return 所有组集合
 382      */
 383     public List<RosterGroup> getGroups() {
 384         if (getConnection() == null)
 385             return null;
 386         List<RosterGroup> groupList = new ArrayList<>();
 387         Collection<RosterGroup> rosterGroup = Roster.getInstanceFor(connection).getGroups();
 388         for (RosterGroup aRosterGroup : rosterGroup) {
 389             groupList.add(aRosterGroup);
 390         }
 391         return groupList;
 392     }
 393
 394     /**
 395      * 获取某个组里面的所有好友
 396      *
 397      * @param groupName 组名
 398      * @return List<RosterEntry>
 399      */
 400     public List<RosterEntry> getEntriesByGroup(String groupName) {
 401         if (getConnection() == null)
 402             return null;
 403         List<RosterEntry> EntriesList = new ArrayList<>();
 404         RosterGroup rosterGroup = Roster.getInstanceFor(connection).getGroup(groupName);
 405         Collection<RosterEntry> rosterEntry = rosterGroup.getEntries();
 406         for (RosterEntry aRosterEntry : rosterEntry) {
 407             EntriesList.add(aRosterEntry);
 408         }
 409         return EntriesList;
 410     }
 411
 412     /**
 413      * 获取所有好友信息
 414      *
 415      * @return List<RosterEntry>
 416      */
 417     public List<RosterEntry> getAllEntries() {
 418         if (getConnection() == null)
 419             return null;
 420         List<RosterEntry> Enlist = new ArrayList<>();
 421         Collection<RosterEntry> rosterEntry = Roster.getInstanceFor(connection).getEntries();
 422         for (RosterEntry aRosterEntry : rosterEntry) {
 423             Enlist.add(aRosterEntry);
 424         }
 425         return Enlist;
 426     }
 427
 428
 429     /**
 430      * 添加一个分组
 431      *
 432      * @param groupName groupName
 433      * @return boolean
 434      */
 435     public boolean addGroup(String groupName) {
 436         if (getConnection() == null)
 437             return false;
 438         try {
 439             Roster.getInstanceFor(connection).createGroup(groupName);
 440             Log.v("addGroup", groupName + "創建成功");
 441             return true;
 442         } catch (Exception e) {
 443             e.printStackTrace();
 444             return false;
 445         }
 446     }
 447
 448     /**
 449      * 删除分组
 450      *
 451      * @param groupName groupName
 452      * @return boolean
 453      */
 454     public boolean removeGroup(String groupName) {
 455         return true;
 456     }
 457
 458
 459     /**
 460      * 文件转字节
 461      *
 462      * @param file file
 463      * @return byte[]
 464      * @throws IOException
 465      */
 466     private byte[] getFileBytes(File file) throws IOException {
 467         BufferedInputStream bis = null;
 468         try {
 469             bis = new BufferedInputStream(new FileInputStream(file));
 470             int bytes = (int) file.length();
 471             byte[] buffer = new byte[bytes];
 472             int readBytes = bis.read(buffer);
 473             if (readBytes != buffer.length) {
 474                 throw new IOException("Entire file not read");
 475             }
 476             return buffer;
 477         } finally {
 478             if (bis != null) {
 479                 bis.close();
 480             }
 481         }
 482     }
 483
 484
 485     /**
 486      * 发送群组聊天消息
 487      *
 488      * @param muc     muc
 489      * @param message 消息文本
 490      */
 491     public void sendGroupMessage(MultiUserChat muc, String message) {
 492         try {
 493             muc.sendMessage(message);
 494         } catch (Exception e) {
 495             e.printStackTrace();
 496         }
 497     }
 498
 499
 500     /**
 501      * 修改密码
 502      *
 503      * @return true成功
 504      */
 505     public boolean changePassword(String pwd) {
 506         if (getConnection() == null)
 507             return false;
 508         try {
 509             AccountManager.getInstance(connection).changePassword(pwd);
 510             return true;
 511         } catch (Exception e) {
 512             e.printStackTrace();
 513             return false;
 514         }
 515     }
 516
 517
 518
 519
 520     /**
 521      * 创建群聊聊天室
 522      *
 523      * @param roomName 聊天室名字
 524      * @param nickName 创建者在聊天室中的昵称
 525      * @param password 聊天室密码
 526      * @return
 527      */
 528     public MultiUserChat createChatRoom(String roomName, String nickName, String password) {
 529         MultiUserChat muc;
 530         try {
 531             // 创建一个MultiUserChat
 532             muc = MultiUserChatManager.getInstanceFor(connection).getMultiUserChat(roomName + "@conference.192.168.0.195");
 533             // 创建聊天室
 534             boolean isCreated = muc.createOrJoin(nickName);
 535             if (isCreated) {
 536                 // 获得聊天室的配置表单
 537                 Form form = muc.getConfigurationForm();
 538                 // 根据原始表单创建一个要提交的新表单。
 539                 Form submitForm = form.createAnswerForm();
 540                 // 向要提交的表单添加默认答复
 541                 List<FormField> fields = form.getFields();
 542                 for (int i = 0; fields != null && i < fields.size(); i++) {
 543                     if (FormField.Type.hidden != fields.get(i).getType() &&
 544                             fields.get(i).getVariable() != null) {
 545                         // 设置默认值作为答复
 546                         submitForm.setDefaultAnswer(fields.get(i).getVariable());
 547                     }
 548                 }
 549                 // 设置聊天室的新拥有者
 550                 List owners = new ArrayList();
 551                 owners.add(connection.getUser());// 用户JID
 552                 submitForm.setAnswer("muc#roomconfig_roomowners", owners);
 553                 // 设置聊天室是持久聊天室,即将要被保存下来
 554                 submitForm.setAnswer("muc#roomconfig_persistentroom", true);
 555                 // 房间仅对成员开放
 556                 submitForm.setAnswer("muc#roomconfig_membersonly", false);
 557                 // 允许占有者邀请其他人
 558                 submitForm.setAnswer("muc#roomconfig_allowinvites", true);
 559                 if (password != null && password.length() != 0) {
 560                     // 进入是否需要密码
 561                     submitForm.setAnswer("muc#roomconfig_passwordprotectedroom", true);
 562                     // 设置进入密码
 563                     submitForm.setAnswer("muc#roomconfig_roomsecret", password);
 564                 }
 565                 // 能够发现占有者真实 JID 的角色
 566                 // submitForm.setAnswer("muc#roomconfig_whois", "anyone");
 567                 // 登录房间对话
 568                 submitForm.setAnswer("muc#roomconfig_enablelogging", true);
 569                 // 仅允许注册的昵称登录
 570                 submitForm.setAnswer("x-muc#roomconfig_reservednick", true);
 571                 // 允许使用者修改昵称
 572                 submitForm.setAnswer("x-muc#roomconfig_canchangenick", false);
 573                 // 允许用户注册房间
 574                 submitForm.setAnswer("x-muc#roomconfig_registration", false);
 575                 // 发送已完成的表单(有默认值)到服务器来配置聊天室
 576                 muc.sendConfigurationForm(submitForm);
 577
 578             } else {
 579
 580             }
 581         } catch (XMPPException | SmackException e) {
 582             e.printStackTrace();
 583
 584             return null;
 585         }
 586         return muc;
 587     }
 588     /**
 589      * 加入一个群聊聊天室
 590      *
 591      * @param jid 聊天室ip 格式为>>群组名称@conference.ip
 592      * @param nickName 用户在聊天室中的昵称
 593      * @param password 聊天室密码 没有密码则传""
 594      * @return
 595      */
 596     public MultiUserChat join(String jid, String nickName, String password) {
 597         try {
 598             // 使用XMPPConnection创建一个MultiUserChat窗口
 599             MultiUserChat muc = MultiUserChatManager.getInstanceFor(connection).getMultiUserChat(jid);
 600             // 聊天室服务将会决定要接受的历史记录数量
 601             DiscussionHistory history = new DiscussionHistory();
 602             history.setMaxChars(0);
 603             // 用户加入聊天室
 604             muc.join(nickName, password);
 605             return muc;
 606         } catch (XMPPException | SmackException e) {
 607             e.printStackTrace();
 608             if ("XMPPError: not-authorized - auth".equals(e.getMessage())) {
 609                 //需要密码加入
 610             }
 611             return null;
 612         }
 613     }
 614     /**
 615      * 获取服务器上的聊天室
 616      */
 617     public List<HostedRoom> getHostedRoom() {
 618         MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
 619         try {
 620             //serviceNames->conference.106.14.20.176
 621             List<String> serviceNames = manager.getServiceNames();
 622             for (int i = 0; i < serviceNames.size(); i++) {
 623                 return manager.getHostedRooms(serviceNames.get(i));
 624             }
 625         } catch (Exception e) {
 626             e.printStackTrace();
 627         }
 628         return null;
 629     }
 630     /**
 631      * @param jid 格式为>>群组名称@conference.ip
 632      */
 633     private void initRoomListener(String jid) {
 634         MultiUserChat multiUserChat = MultiUserChatManager.getInstanceFor(connection).getMultiUserChat(jid);
 635         multiUserChat.addMessageListener(new MessageListener() {
 636             @Override
 637             public void processMessage(final Message message) {
 638                 //当消息返回为空的时候,表示用户正在聊天窗口编辑信息并未发出消息
 639                 if (!TextUtils.isEmpty(message.getBody())) {
 640                     //收到的消息
 641                 }
 642             }
 643         });
 644         //发送群聊消息
 645 //        MultiUserChat multiUserChat = MultiUserChatManager.getInstanceFor(connection).getMultiUserChat(jid);
 646 //        multiUserChat.sendMessage("Hello World");
 647
 648     }
 649
 650 //    /**
 651 //     * 创建房间
 652 //     *
 653 //     * @param roomName 房间名称
 654 //     */
 655 //    public MultiUserChat createRoom(String roomName, String password) {
 656 //        if (getConnection() == null)
 657 //            return null;
 658 //
 659 //        MultiUserChat muc = null;
 660 //        try {
 661 //            // 创建一个MultiUserChat
 662 //            muc = MultiUserChatManager.getInstanceFor(connection).getMultiUserChat(roomName+"@conference.192.168.0.195");
 663 //            // 创建聊天室
 664 //            muc.create(roomName);
 665 //            // 获得聊天室的配置表单
 666 //            Form form = muc.getConfigurationForm();
 667 //            // 根据原始表单创建一个要提交的新表单。
 668 //            Form submitForm = form.createAnswerForm();
 669 //            // 向要提交的表单添加默认答复
 670 //            for (FormField formField : form.getFields()) {
 671 //                if (FormField.Type.hidden == formField.getType()
 672 //                        && formField.getVariable() != null) {
 673 //                    // 设置默认值作为答复
 674 //                    submitForm.setDefaultAnswer(formField.getVariable());
 675 //                }
 676 //            }
 677 //            // 设置聊天室的新拥有者
 678 //            List<String> owners = new ArrayList<>();
 679 //            owners.add(getConnection().getUser());// 用户JID
 680 //            submitForm.setAnswer("muc#roomconfig_roomowners", owners);
 681 //            // 设置聊天室是持久聊天室,即将要被保存下来
 682 //            submitForm.setAnswer("muc#roomconfig_persistentroom", true);
 683 //            // 房间仅对成员开放
 684 //            submitForm.setAnswer("muc#roomconfig_membersonly", false);
 685 //            // 允许占有者邀请其他人
 686 //            submitForm.setAnswer("muc#roomconfig_allowinvites", true);
 687 //            if (!password.equals("")) {
 688 //                // 进入是否需要密码
 689 //                submitForm.setAnswer("muc#roomconfig_passwordprotectedroom",
 690 //                        true);
 691 //                // 设置进入密码
 692 //                submitForm.setAnswer("muc#roomconfig_roomsecret", password);
 693 //            }
 694 //            // 能够发现占有者真实 JID 的角色
 695 //            // submitForm.setAnswer("muc#roomconfig_whois", "anyone");
 696 //            // 登录房间对话
 697 //            submitForm.setAnswer("muc#roomconfig_enablelogging", true);
 698 //            // 仅允许注册的昵称登录
 699 //            submitForm.setAnswer("x-muc#roomconfig_reservednick", true);
 700 //            // 允许使用者修改昵称
 701 //            submitForm.setAnswer("x-muc#roomconfig_canchangenick", false);
 702 //            // 允许用户注册房间
 703 //            submitForm.setAnswer("x-muc#roomconfig_registration", false);
 704 //            // 发送已完成的表单(有默认值)到服务器来配置聊天室
 705 //            muc.sendConfigurationForm(submitForm);
 706 //        } catch (Exception e) {
 707 //            e.printStackTrace();
 708 //            LoggerUtil.systemOut(e.toString());
 709 //            return null;
 710 //        }
 711 //        return muc;
 712 //    }
 713
 714     /**
 715      * 加入会议室
 716      *
 717      * @param user      昵称
 718      * @param roomsName 会议室名
 719      */
 720     public MultiUserChat joinMultiUserChat(String user, String roomsName) {
 721         if (getConnection() == null)
 722             return null;
 723         try {
 724             // 使用XMPPConnection创建一个MultiUserChat窗口
 725             MultiUserChat muc = MultiUserChatManager.getInstanceFor(connection).getMultiUserChat(connection.getServiceName());
 726
 727             // 用户加入聊天室
 728             muc.join(user);
 729
 730             Log.i("MultiUserChat", "会议室【" + roomsName + "】加入成功........");
 731             return muc;
 732         } catch (Exception e) {
 733             e.printStackTrace();
 734             Log.i("MultiUserChat", "会议室【" + roomsName + "】加入失败........");
 735             return null;
 736         }
 737     }
 738
 739
 740
 741
 742     /**
 743      * 判断是否是好友
 744      *
 745      * @param
 746      * @param user
 747      * @return
 748      */
 749     public boolean isMyFriend(String user) {
 750
 751         List<RosterEntry> allEntries = XmppConnection.getInstance().getAllEntries();
 752         for (int i = 0; i < allEntries.size(); i++) {
 753             LoggerUtil.systemOut("allEntries.get(i).getUser() == " + allEntries.get(i).getUser());
 754             LoggerUtil.systemOut("user == " + user);
 755             if (allEntries.get(i).getUser().equals(user)) {
 756                 LoggerUtil.systemOut(allEntries.get(i).getType().toString() + "type");
 757                 if (allEntries.get(i).getType().toString().equals("both")) {
 758                     return true;
 759                 } else {
 760                     return false;
 761                 }
 762             }
 763         }
 764         return false;
 765
 766     }
 767     /**
 768      * 查询会议室成员名字
 769      *
 770      * @param muc
 771      */
 772     public List<String> findMulitUser(MultiUserChat muc) {
 773         if (getConnection() == null)
 774             return null;
 775         List<String> listUser = new ArrayList<>();
 776         List<String> occupants = muc.getOccupants();
 777         // 遍历出聊天室人员名称
 778         for (String entityFullJid : occupants) {
 779             // 聊天室成员名字
 780             String name = entityFullJid;
 781             listUser.add(name);
 782         }
 783         return listUser;
 784     }
 785
 786
 787     /**
 788      * 判断OpenFire用户的状态 strUrl :
 789      * url格式 - http://my.openfire.com:9090/plugins/presence
 790      * /status?jid=user1@SERVER_NAME&type=xml
 791      * 返回值 : 0 - 用户不存在; 1 - 用户在线; 2 - 用户离线
 792      * 说明 :必须要求 OpenFire加载 presence 插件,同时设置任何人都可以访问
 793      */
 794     public int IsUserOnLine(String user) {
 795         String url = "http://" + SERVER_HOST + ":9090/plugins/presence/status?" +
 796                 "jid=" + user;
 797         int shOnLineState = 0; // 不存在
 798         try {
 799             URL oUrl = new URL(url);
 800             URLConnection oConn = oUrl.openConnection();
 801             if (oConn != null) {
 802                 BufferedReader oIn = new BufferedReader(new InputStreamReader(
 803                         oConn.getInputStream()));
 804                 String strFlag = oIn.readLine();
 805                 oIn.close();
 806                 System.out.println("strFlag" + strFlag);
 807                 if (strFlag.contains("type=\"unavailable\"")) {
 808                     shOnLineState = 2;
 809                 }
 810                 if (strFlag.contains("type=\"error\"")) {
 811                     shOnLineState = 0;
 812                 } else if (strFlag.contains("priority") || strFlag.contains("id=\"")) {
 813                     shOnLineState = 1;
 814                 }
 815             }
 816         } catch (Exception e) {
 817             e.printStackTrace();
 818         }
 819
 820         return shOnLineState;
 821     }
 822
 823     /**
 824      * 创建聊天窗口
 825      *
 826      * @param JID JID
 827      * @return Chat
 828      */
 829     public Chat getFriendChat(String JID, ChatMessageListener listener) {
 830         try {
 831             return ChatManager.getInstanceFor(XmppConnection.getInstance().getConnection())
 832                     .createChat(JID, listener);
 833         } catch (Exception e) {
 834             e.printStackTrace();
 835         }
 836         return null;
 837     }
 838
 839     /**
 840      * 发送单人聊天消息
 841      *
 842      * @param chat    chat
 843      * @param message 消息文本
 844      */
 845     public void sendSingleMessage(Chat chat, String message) {
 846         try {
 847             chat.sendMessage(message);
 848         } catch (SmackException.NotConnectedException e) {
 849             e.printStackTrace();
 850         }
 851     }
 852
 853     /**
 854      * 发消息
 855      *
 856      * @param chat    chat
 857      * @param muc     muc
 858      * @param message message
 859      */
 860     public void sendMessage(Chat chat, MultiUserChat muc, String message) {
 861         if (chat != null) {
 862             sendSingleMessage(chat, message);
 863         } else if (muc != null) {
 864             sendGroupMessage(muc, message);
 865         }
 866     }
 867
 868
 869     /**
 870      * 获取离线消息
 871      *
 872      * @return
 873      */
 874     int i = 0;
 875
 876     public void getHisMessage(Context context) {
 877         LoggerUtil.systemOut("访问次数 " + (i++));
 878         setPresence(5);
 879         if (getConnection() == null)
 880             return;
 881
 882         try {
 883             OfflineMessageManager offlineManager = new OfflineMessageManager(getConnection());
 884             List<Message> messageList = offlineManager.getMessages();
 885             int count = offlineManager.getMessageCount();
 886             LoggerUtil.systemOut("离线消息个数" + count);
 887             if (count <= 0) {
 888                 setPresence(0);
 889                 return;
 890             }
 891             for (Message message : messageList) {
 892                 String[] send = message.getFrom().split("@");// 发送方
 893                 String[] receiver = message.getTo().split("@");// 接收方
 894                 saveofflineMessage(context, receiver[0], send[0], send[0], message.getBody(), "chat");
 895                 saveofflineChatData(context, receiver[0], send[0], send[0], message.getBody());
 896
 897             }
 898             offlineManager.deleteMessages();
 899         } catch (Exception e) {
 900             e.printStackTrace();
 901         }
 902         setPresence(0);
 903     }
 904
 905     public boolean saveofflineMessage(Context context, String main, final String users, final String to, final String content, String type) {
 906
 907         Cursor cursor = MessageDao.getInstance(context).queryIshasResult(context, main, type);
 908
 909         if (cursor != null) {
 910             //更新
 911             if (type.equals("add")) {
 912                 int result = cursor.getInt(cursor.getColumnIndex("result"));
 913                 if (result == 0) {
 914                     int id = cursor.getInt(cursor.getColumnIndex("id"));
 915                     MessageDao.getInstance(context).update(context, id, content, 1);
 916                     return true;
 917                 } else {
 918                     return false;
 919                 }
 920             } else {
 921                 int id = cursor.getInt(cursor.getColumnIndex("id"));
 922                 MessageDao.getInstance(context).update(context, id, content, 1);
 923                 return true;
 924             }
 925
 926         } else {
 927             //插入
 928             List<XmppUser> list1 = XmppConnection.getInstance().searchUsers(users);
 929             XmppMessage xm = new XmppMessage(to,
 930                     type,
 931                     new XmppUser(list1.get(0).getUserName(), list1.get(0).getName()),
 932                     TimeUtil.getDate(),
 933                     content,
 934                     1,
 935                     main
 936             );
 937             LoggerUtil.systemOut("to" + to);
 938             MessageDao.getInstance(context).inserts(context, xm);
 939
 940             return true;
 941         }
 942
 943
 944     }
 945
 946     public void saveofflineChatData(Context context, String main, final String users, final String to, final String content) {
 947         XmppChat xc = new XmppChat(main, users, "", "", 2, content, to, 1, new Date().getTime());
 948         FriendChatDao.getInstance(context).insert(context, xc);
 949     }
 950
 951     /**
 952      * 注册
 953      *
 954      * @param account  注册帐号
 955      * @param password 注册密码
 956      * @return 1、注册成功 0、注册失败
 957      */
 958     public boolean register(String account, String password, String nickName) {
 959         if (getConnection() == null)
 960             return false;
 961         try {
 962 //            new
 963             Map<String, String> attributes = new HashMap<>();
 964             attributes.put("name", nickName);
 965             AccountManager.getInstance(connection).createAccount(account, password, attributes);
 966
 967         } catch (XMPPException | SmackException e) {
 968             e.printStackTrace();
 969             return false;
 970         }
 971
 972         return true;
 973     }
 974
 975
 976     /**
 977      * 设置昵称
 978      *
 979      * @param
 980      * @param rosterEntry
 981      * @return
 982      */
 983     public boolean setNickName(RosterEntry rosterEntry, String nickName) {
 984         try {
 985             rosterEntry.setName(nickName);
 986             return true;
 987         } catch (SmackException.NotConnectedException e) {
 988             e.printStackTrace();
 989             return false;
 990         } catch (SmackException.NoResponseException e) {
 991             e.printStackTrace();
 992             return false;
 993         } catch (XMPPException.XMPPErrorException e) {
 994             e.printStackTrace();
 995             return false;
 996         }
 997     }
 998
 999     private OutgoingFileTransfer fileTransfer;
1000
1001     // 发送文件
1002     public void sendFile(String user, File file) throws Exception {
1003
1004         FileTransferManager instanceFor = FileTransferManager.getInstanceFor(connection);
1005
1006         fileTransfer = instanceFor.createOutgoingFileTransfer(user);
1007         fileTransfer.sendFile(file, "send file");
1008
1009         System.out.println("发送成功" + user + file.exists() + "文件路径" + file.getPath());
1010     }
1011
1012     /*
1013      * 语音接收文件监听接收文件
1014      *
1015      * @author Administrator
1016      *
1017      */
1018     private FileTransferListener mfiletransfransferlistener;//接受语音文件监听
1019
1020     public void receivedFile() {
1021
1022         // Create the file transfer manager
1023
1024         FileTransferManager manager = FileTransferManager.getInstanceFor(connection);
1025         mfiletransfransferlistener = new FileTransferListener() {
1026             public void fileTransferRequest(FileTransferRequest request) {
1027                 // Check to see if the request should be accepted
1028
1029                 LoggerUtil.systemOut("有文件接收了" + request.toString());
1030                 // Accept it
1031                 IncomingFileTransfer transfer = request.accept();
1032                 try {
1033
1034                     File filePath = new File(Environment.getExternalStorageDirectory(), "fcyt");
1035
1036                     if (!filePath.exists()) {
1037                         filePath.mkdirs();
1038                     }
1039 //                    File file = new File( Environment
1040 //                            .getExternalStorageDirectory()+"/fcyt/"
1041 //                            +"/"+ request.getFileName());
1042
1043
1044                     String streamID = request.getStreamID();
1045
1046                     LoggerUtil.systemOut("streamID", streamID);
1047                     File file = new File(filePath, request.getFileName());
1048                     System.out.println(request.getFileName() + "接收路径" + file.getPath() + "接收语音文件名称" + file.exists());
1049
1050                     transfer.recieveFile(file);
1051
1052                 } catch (Exception e) {
1053                     e.printStackTrace();
1054                 }
1055
1056             }
1057         };
1058
1059
1060         manager.addFileTransferListener(mfiletransfransferlistener);
1061
1062     }
1063
1064     /**
1065      * 查找用户
1066      *
1067      * @param
1068      * @param userName
1069      * @return
1070      */
1071     public List<XmppUser> searchUsers(String userName) {
1072         List<XmppUser> list = new ArrayList<XmppUser>();
1073         UserSearchManager userSearchManager = new UserSearchManager(connection);
1074         try {
1075             Form searchForm = userSearchManager.getSearchForm("search."
1076                     + connection.getServiceName());
1077             Form answerForm = searchForm.createAnswerForm();
1078             answerForm.setAnswer("Username", true);
1079             answerForm.setAnswer("Name", true);
1080             answerForm.setAnswer("search", userName);
1081             ReportedData data = userSearchManager.getSearchResults(answerForm, "search." + connection.getServiceName());
1082             List<ReportedData.Row> rows = data.getRows();
1083             for (ReportedData.Row row : rows) {
1084                 XmppUser user = new XmppUser(null, null);
1085                 user.setUserName(row.getValues("Username").toString().replace("]", "").replace("[", ""));
1086                 user.setName(row.getValues("Name").toString().replace("]", "").replace("[", ""));
1087                 list.add(user);
1088             }
1089
1090         } catch (Exception e) {
1091
1092         }
1093         return list;
1094     }
1095
1096     public static void configure(ProviderManager pm) {
1097
1098         try {
1099             Class.forName("org.jivesoftware.smack.ReconnectionManager");
1100         } catch (Exception e) {
1101             e.printStackTrace();
1102         }
1103
1104         // Private Data Storage
1105         pm.addIQProvider("query", "jabber:iq:private", new PrivateDataManager.PrivateDataIQProvider());
1106
1107         // Time
1108         try {
1109             pm.addIQProvider("query", "jabber:iq:time", Class.forName("org.jivesoftware.smackx.packet.Time"));
1110         } catch (ClassNotFoundException e) {
1111             Log.w("TestClient", "Can't load class for org.jivesoftware.smackx.packet.Time");
1112         }
1113
1114 //        // Roster Exchange
1115 //        pm.addExtensionProvider("x", "jabber:x:roster", new RosterLoadedListener() {
1116 //        });
1117 //
1118 //        // Message Events
1119 //        pm.addExtensionProvider("x", "jabber:x:event", new MessageEventProvider());
1120
1121         // Chat State
1122         pm.addExtensionProvider("active", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
1123         pm.addExtensionProvider("composing", "http://jabber.org/protocol/chatstates",
1124                 new ChatStateExtension.Provider());
1125         pm.addExtensionProvider("paused", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
1126         pm.addExtensionProvider("inactive", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
1127         pm.addExtensionProvider("gone", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
1128
1129         // XHTML
1130         pm.addExtensionProvider("html", "http://jabber.org/protocol/xhtml-im", new XHTMLExtensionProvider());
1131
1132         // Group Chat Invitations
1133         pm.addExtensionProvider("x", "jabber:x:conference", new GroupChatInvitation.Provider());
1134
1135         // Service Discovery # Items
1136         pm.addIQProvider("query", "http://jabber.org/protocol/disco#items", new DiscoverItemsProvider());
1137
1138         // Service Discovery # Info
1139         pm.addIQProvider("query", "http://jabber.org/protocol/disco#info", new DiscoverInfoProvider());
1140
1141         // Data Forms
1142         pm.addExtensionProvider("x", "jabber:x:data", new DataFormProvider());
1143
1144         // MUC User
1145         pm.addExtensionProvider("x", "http://jabber.org/protocol/muc#user", new MUCUserProvider());
1146
1147         // MUC Admin
1148         pm.addIQProvider("query", "http://jabber.org/protocol/muc#admin", new MUCAdminProvider());
1149
1150         // MUC Owner
1151         pm.addIQProvider("query", "http://jabber.org/protocol/muc#owner", new MUCOwnerProvider());
1152
1153         // Delayed Delivery
1154         pm.addExtensionProvider("x", "jabber:x:delay", new DelayInformationProvider());
1155
1156         // Version
1157         try {
1158             pm.addIQProvider("query", "jabber:iq:version", Class.forName("org.jivesoftware.smackx.packet.Version"));
1159         } catch (ClassNotFoundException e) {
1160             // Not sure what's happening here.
1161         }
1162
1163         // VCard
1164         pm.addIQProvider("vCard", "vcard-temp", new VCardProvider());
1165
1166         // Offline Message Requests
1167         pm.addIQProvider("offline", "http://jabber.org/protocol/offline", new OfflineMessageRequest.Provider());
1168
1169         // Offline Message Indicator
1170         pm.addExtensionProvider("offline", "http://jabber.org/protocol/offline", new OfflineMessageInfo.Provider());
1171
1172         // Last Activity
1173         pm.addIQProvider("query", "jabber:iq:last", new LastActivity.Provider());
1174
1175         // User Search
1176         pm.addIQProvider("query", "jabber:iq:search", new UserSearch.Provider());
1177
1178         // SharedGroupsInfo
1179         pm.addIQProvider("sharedgroup", "http://www.jivesoftware.org/protocol/sharedgroup",
1180                 new SharedGroupsInfo.Provider());
1181
1182         // JEP-33: Extended Stanza Addressing
1183         pm.addExtensionProvider("addresses", "http://jabber.org/protocol/address", new MultipleAddressesProvider());
1184
1185         // FileTransfer
1186         pm.addIQProvider("si", "http://jabber.org/protocol/si", new StreamInitiationProvider());
1187         pm.addIQProvider("query", "http://jabber.org/protocol/bytestreams", new BytestreamsProvider());
1188         pm.addIQProvider("open", "http://jabber.org/protocol/ibb", new OpenIQProvider());
1189         pm.addIQProvider("close", "http://jabber.org/protocol/ibb", new CloseIQProvider());
1190 //        pm.addExtensionProvider("data", "http://jabber.org/protocol/ibb", new DataPacketProvider());
1191
1192         // Privacy
1193         pm.addIQProvider("query", "jabber:iq:privacy", new PrivacyProvider());
1194         pm.addIQProvider("command", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider());
1195         pm.addExtensionProvider("malformed-action", "http://jabber.org/protocol/commands",
1196                 new AdHocCommandDataProvider.MalformedActionError());
1197         pm.addExtensionProvider("bad-locale", "http://jabber.org/protocol/commands",
1198                 new AdHocCommandDataProvider.BadLocaleError());
1199         pm.addExtensionProvider("bad-payload", "http://jabber.org/protocol/commands",
1200                 new AdHocCommandDataProvider.BadPayloadError());
1201         pm.addExtensionProvider("bad-sessionid", "http://jabber.org/protocol/commands",
1202                 new AdHocCommandDataProvider.BadSessionIDError());
1203         pm.addExtensionProvider("session-expired", "http://jabber.org/protocol/commands",
1204                 new AdHocCommandDataProvider.SessionExpiredError());
1205     }
1206
1207
1208 }


XmppService后台监听接收消息

import android.app.Service;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Handler;
import android.os.IBinder;
import android.os.Vibrator;
import android.util.Log;import org.greenrobot.eventbus.EventBus;
import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.StanzaListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Stanza;import java.util.Date;
import java.util.HashMap;
import java.util.List;import cnpc.fcyt.fcydyy.R;
import cnpc.fcyt.fcydyy.constant.ConfigConstants;
import cnpc.fcyt.fcydyy.event.LogoutEvent;
import cnpc.fcyt.fcydyy.event.RefreshChatMessageEvent;
import cnpc.fcyt.fcydyy.event.RefreshRedDotEvent;
import cnpc.fcyt.fcydyy.util.LoggerUtil;
import cnpc.fcyt.fcydyy.xmpp.bean.XmppChat;
import cnpc.fcyt.fcydyy.xmpp.bean.XmppMessage;
import cnpc.fcyt.fcydyy.xmpp.bean.XmppUser;
import cnpc.fcyt.fcydyy.xmpp.dao.FriendChatDao;
import cnpc.fcyt.fcydyy.xmpp.dao.MessageDao;
import cnpc.fcyt.fcydyy.xmpp.util.SaveUserUtil;
import cnpc.fcyt.fcydyy.xmpp.util.TimeUtil;
import cnpc.fcyt.fcydyy.xmpp.util.UserConstants;public class XmppService extends Service {private XMPPConnection con;public static ContentResolver resolver;public static HashMap<String, Object> map;String send[];//发送方String receiver[];//接收方public static String user;public static SoundPool pool;public static Vibrator vibrator;Handler handler = new Handler() {@Overridepublic void handleMessage(android.os.Message msg) {super.handleMessage(msg);if (msg.what == 1) {boolean authenticated = XmppConnection.getInstance().isAuthenticated();AbstractXMPPConnection connection = XmppConnection.getInstance().getConnection();if (connection!=null){boolean connected = connection.isConnected();if (!connected){LoggerUtil.systemOut("IM服务器无法连接");XmppConnection.getInstance().setConnectionToNull();EventBus.getDefault().post(new LogoutEvent());}else {if (!authenticated) {LoggerUtil.systemOut("掉线了");EventBus.getDefault().post(new LogoutEvent());}else {LoggerUtil.systemOut("连接ing");}}}handler.sendEmptyMessageDelayed(1, 3000);}}};@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();resolver = getContentResolver();map = new HashMap<>();con = XmppConnection.getInstance().getConnection();user = SaveUserUtil.loadAccount(XmppService.this).getUser();pool = new SoundPool(10, AudioManager.STREAM_SYSTEM, 5);pool.load(this, R.raw.tishi, 1);vibrator = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE);LoggerUtil.systemOut("启动服务......");handler.sendEmptyMessageDelayed(1, 3000);}@Overridepublic IBinder onBind(Intent intent) {return null;}String messageID = "";@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {//'zS4Xw-62if (null != con && con.isConnected()) {con.addAsyncStanzaListener(new StanzaListener() {@Overridepublic void processPacket(Stanza packet) throws SmackException.NotConnectedException {String stanzaId = packet.getStanzaId();LoggerUtil.systemOut(stanzaId + "消息ID");LoggerUtil.systemOut("messageID" + messageID);if (messageID.equals(stanzaId) || stanzaId == null) {} else {if (stanzaId != null) {messageID = stanzaId;}LoggerUtil.systemOut(packet.toString() + "通知来了");if (packet instanceof Presence) {Presence presence = (Presence) packet;send = presence.getFrom().split("@");// 发送方receiver = presence.getTo().split("@");// 接收方// Presence.Type有7中状态LoggerUtil.systemOut(presence.getType() + "信息类型");if (presence.getType().equals(Presence.Type.subscribe)) {// 好友申请LoggerUtil.systemOut(send[0] + "\t好友申请加为好友\t type="+ presence.getType().toString());sendBroad("add");} else if (presence.getType().equals(Presence.Type.subscribed)) {// 同意添加好友LoggerUtil.systemOut(send[0] + "\t同意添加好友\t type="+ presence.getType().toString());sendBroad("tongyi");} else if (presence.getType().equals(Presence.Type.unsubscribe)) {// 删除好友LoggerUtil.systemOut(send[0] + "\t删除好友\t type="+ presence.getType().toString());} else if (presence.getType().equals(Presence.Type.unsubscribed)) {// 拒绝对放的添加请求LoggerUtil.systemOut(send[0] + "\t拒绝添加好友\t type="+ presence.getType().toString());sendBroad("jujue");} else if (presence.getType().equals(Presence.Type.unavailable)) {// 好友下线Log.i("service", send[0] + "\t 下线了");LoggerUtil.systemOut(send[0] + "\t下线了\t type="+ presence.getType().toString());sendBroad("status", 6);} else if (presence.getType().equals(Presence.Type.available)) {// 好友上线//0.在线 1.Q我吧 2.忙碌 3.勿扰 4.离开 5.隐身 6.离线if (presence.getMode() == Presence.Mode.chat) {//Q我吧Log.i("service", send[0] + "\t 的状态改为了 Q我吧");sendBroad("status", 1);} else if (presence.getMode() == Presence.Mode.dnd) {//忙碌Log.i("service", send[0] + "\t 的状态改为了 忙碌了");sendBroad("status", 2);} else if (presence.getMode() == Presence.Mode.xa) {//忙碌Log.i("service", send[0] + "\t 的状态改为了 勿扰了");sendBroad("status", 3);} else if (presence.getMode() == Presence.Mode.away) {//离开Log.i("service", send[0] + "\t 的状态改为了 离开了");sendBroad("status", 4);} else {Log.i("service", send[0] + "\t 的状态改为了 上线了");sendBroad("status", 0);}}} else if (packet instanceof Message) {Message msg = (Message) packet;EventBus.getDefault().post(new RefreshRedDotEvent());int viewType;if (msg.getBody() != null) {if (msg.getBody().length() > 3 && msg.getBody().toString().substring(0, 4).equals("http")) {viewType = 2;} else {viewType = 1;}XmppChat xc = new XmppChat(UserConstants.loginuser, packet.getFrom().replace(UserConstants.chatDoMain, ""), "", "", 2,                       msg.getBody().toString(), packet.getFrom().replace(UserConstants.chatDoMain, ""), viewType, new Date().getTime());FriendChatDao.getInstance(XmppService.this).insert(XmppService.this, xc);sendBroad("chat", xc);}}}}}, null);}return super.onStartCommand(intent, flags, startId);}private void sendBroad(String type, XmppChat xc) {Intent intent;intent = new Intent("xmpp_receiver");intent.putExtra("type", type);intent.putExtra("chat", xc);sendBroadcast(intent);}private void sendBroad(String type, int status) {map.put(send[0], status);Intent intent;intent = new Intent("xmpp_receiver");intent.putExtra("type", type);sendBroadcast(intent);}private void sendBroad(String type) {String str_content = "";String str_type = "";switch (type) {case "add":str_content = "请求加为好友";str_type = "add";break;case "tongyi":str_content = "同意添加好友";str_type = "tongyi";break;case "jujue":str_content = "拒绝添加好友";str_type = "jujue";break;}LoggerUtil.systemOut(send[0] + "发送人");LoggerUtil.systemOut(receiver[0] + "接收人");if (msgDatas(receiver[0], send[0], send[0], str_content, str_type)) {if (pool != null && ConfigConstants.getSound(this)) {pool.play(1, 1, 1, 0, 0, 1);}if (vibrator != null && ConfigConstants.getShake(this)) {vibrator.vibrate(500);}Intent intent;intent = new Intent("xmpp_receiver");intent.putExtra("type", type);sendBroadcast(intent);}}public boolean msgDatas(final String main, final String users, final String to, final String content, String type) {Cursor cursor = MessageDao.getInstance(this).queryIshasResult(this, main, type);if (cursor != null) {//更新if (type.equals("add")) {int result = cursor.getInt(cursor.getColumnIndex("result"));if (result == 0) {int id = cursor.getInt(cursor.getColumnIndex("id"));MessageDao.getInstance(this).update(this, id, content, 1);//刷新聊天页面EventBus.getDefault().post(new RefreshChatMessageEvent());return true;} else {return false;}} else {int id = cursor.getInt(cursor.getColumnIndex("id"));MessageDao.getInstance(this).update(this, id, content, 1);//刷新聊天页面EventBus.getDefault().post(new RefreshChatMessageEvent());return true;}} else {//插入List<XmppUser> list1 = XmppConnection.getInstance().searchUsers(users);XmppMessage xm = new XmppMessage(to,type,new XmppUser(list1.get(0).getUserName(), list1.get(0).getName()),TimeUtil.getDate(),content,1,main);LoggerUtil.systemOut("to" + to);MessageDao.getInstance(this).inserts(this, xm);//刷新聊天页面EventBus.getDefault().post(new RefreshChatMessageEvent());return true;}}}


XmppReceiver消息广播处理消息

import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Build;
import android.support.v4.app.NotificationCompat;import org.greenrobot.eventbus.EventBus;import java.util.List;import cnpc.fcyt.fcydyy.R;
import cnpc.fcyt.fcydyy.constant.ConfigConstants;
import cnpc.fcyt.fcydyy.event.RefreshChatMessageEvent;
import cnpc.fcyt.fcydyy.util.LoggerUtil;
import cnpc.fcyt.fcydyy.xmpp.bean.XmppChat;
import cnpc.fcyt.fcydyy.xmpp.bean.XmppMessage;
import cnpc.fcyt.fcydyy.xmpp.bean.XmppUser;
import cnpc.fcyt.fcydyy.xmpp.dao.MessageDao;
import cnpc.fcyt.fcydyy.xmpp.util.TimeUtil;public class XmppReceiver extends BroadcastReceiver {updateActivity ua = null;public NotificationManager manager = null;Context context;public XmppReceiver(updateActivity ua) {this.ua = ua;}@TargetApi(Build.VERSION_CODES.JELLY_BEAN)@Overridepublic void onReceive(Context context, Intent intent) {this.context = context;String type = intent.getStringExtra("type");if (type.equals("chat")) {LoggerUtil.systemOut("有新的接收消息");XmppChat xc = (XmppChat) intent.getSerializableExtra("chat");if (ChatActivity.ca != null) {LoggerUtil.systemOut(ChatActivity.ca.user + "当前聊天用户");LoggerUtil.systemOut(xc.getUser() + "新信息的用户");LoggerUtil.systemOut(xc.getToo() + "当前聊天用户too");if ((ChatActivity.ca.user).equals(xc.getToo())) {ua.update(xc);}chatDatas(xc.getMain(), xc.getUser(), xc.getToo(), xc.getContent());} else {int num = chatData(xc.getMain(), xc.getUser(), xc.getToo(), xc.getContent());if (XmppService.vibrator != null && ConfigConstants.getShake(context)) {XmppService.vibrator.vibrate(500);}if (!isAppOnForeground(context)) {//在message界面更新信息if (manager == null) {manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);}Intent intent1 = new Intent(context, ChatActivity.class);intent1.putExtra("user", xc.getUser());PendingIntent pi = PendingIntent.getActivity(context, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);List<XmppUser> xmppUsers = XmppConnection.getInstance().searchUsers(xc.getUser());Notification notify = new Notification.Builder(context).setAutoCancel(true).setTicker("有新消息").setSmallIcon(R.mipmap.ic_launcher).setContentTitle("来自" +  xmppUsers.get(0).getName() + "的消息").setContentText(xc.getContent()).setDefaults(NotificationCompat.FLAG_ONLY_ALERT_ONCE).setWhen(System.currentTimeMillis()).setNumber(num).setContentIntent(pi).build();manager.notify(0, notify);} else {if (XmppService.pool != null && ConfigConstants.getSound(context)) {XmppService.pool.play(1, 1, 1, 0, 0, 1);}}}}ua.update(type);}public interface updateActivity {public void update(String type);public void update(XmppChat xc);}public int chatData(final String main, final String users, final String to, final String content) {Cursor cursor = MessageDao.getInstance(context).queryIshasResult(context, main, "chat");if (cursor != null) {//更新int id = cursor.getInt(cursor.getColumnIndex("id"));int result = cursor.getInt(cursor.getColumnIndex("result"));MessageDao.getInstance(context).update(context, id, content, result + 1);//刷新聊天页面EventBus.getDefault().post(new RefreshChatMessageEvent());return (result + 1);} else {//插入List<XmppUser> list1 = XmppConnection.getInstance().searchUsers(users);XmppMessage xm = new XmppMessage(to,"chat",new XmppUser(list1.get(0).getUserName(), list1.get(0).getName()),TimeUtil.getDate(),content,1,main);LoggerUtil.systemOut("to3" + to);MessageDao.getInstance(context).inserts(context, xm);//刷新聊天页面EventBus.getDefault().post(new RefreshChatMessageEvent());return 1;}}public void chatDatas(final String main, final String users, final String to, final String content) {int id = MessageDao.getInstance(context).queryIshas(context, main, "chat");if (id != -1) {//更新MessageDao.getInstance(context).update(context, id, content, 0);} else {//插入List<XmppUser> list1 = XmppConnection.getInstance().searchUsers(users);XmppMessage xm = new XmppMessage(to,"chat",new XmppUser(list1.get(0).getUserName(), list1.get(0).getName()),TimeUtil.getDate(),content,0,main);LoggerUtil.systemOut("to1" + to);MessageDao.getInstance(context).inserts(context, xm);}//刷新聊天页面EventBus.getDefault().post(new RefreshChatMessageEvent());}public boolean isAppOnForeground(Context context) {// Returns a list of application processes that are running on the// device
ActivityManager activityManager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);String packageName = context.getApplicationContext().getPackageName();List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();if (appProcesses == null)return false;for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {// The name of the process that this object is associated with.if (appProcess.processName.equals(packageName)&& appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {return true;}}return false;}}

本地数据库建立,用于储存历史消息记录等

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;import java.util.ArrayList;import cnpc.fcyt.fcydyy.util.LoggerUtil;
import cnpc.fcyt.fcydyy.xmpp.bean.XmppChat;public class FriendChatDao {private static FriendChatDao mInstance;public Context context;private FriendChatDao(Context ctx) {this.context = ctx;}public static FriendChatDao getInstance(Context ctx) {//懒汉: 考虑线程安全问题, 两种方式: 1. 给方法加同步锁 synchronized, 效率低; 2. 给创建对象的代码块加同步锁//读数据不会出现线程安全问题, 写数据会出现线程安全问题//a, B, Cif (mInstance == null) {//B, Csynchronized (FriendChatDao.class) {//aif (mInstance == null) {mInstance = new FriendChatDao(ctx);}}}return mInstance;}public boolean insert(Context context, XmppChat xc) {boolean isSucceed = false;// 1. 在内存中创建数据库帮助类的对象FriendChatOpenHelper helper = new FriendChatOpenHelper(context);// 2. 在磁盘上创建数据库文件SQLiteDatabase db = helper.getWritableDatabase();/*** table        :表名* nullColumnHack:*/ContentValues values = new ContentValues();values.put("main", xc.getMain());values.put("user", xc.getUser());values.put("nickname", xc.getNickname());values.put("icon", xc.getIcon());values.put("type", xc.getType());values.put("content", xc.getContent());values.put("too", xc.getToo());values.put("viewtype", xc.getViewType());values.put("time", xc.getTime());long id = db.insert("chat", null, values);if (id == -1) {LoggerUtil.systemOut("插入失败");isSucceed = false;} else {LoggerUtil.systemOut("插入成功");isSucceed = true;}// 释放资源
        db.close();return isSucceed;}public ArrayList<XmppChat> query(Context context, String main, String too) {// 1. 在内存中创建数据库帮助类的对象FriendChatOpenHelper helper = new FriendChatOpenHelper(context);// 2. 在磁盘上创建数据库文件SQLiteDatabase database = helper.getWritableDatabase();Cursor cursor = database.query("chat", null, "too=?", new String[]{too}, null, null, null);ArrayList<XmppChat> list = new ArrayList<>();if (cursor != null) {LoggerUtil.systemOut("查询个数 " + cursor.getCount());while (cursor.moveToNext()) {String user = cursor.getString(cursor.getColumnIndex("user"));String nickname = cursor.getString(cursor.getColumnIndex("nickname"));String icon = cursor.getString(cursor.getColumnIndex("icon"));int type = cursor.getInt(cursor.getColumnIndex("type"));String content = cursor.getString(cursor.getColumnIndex("content"));String times = cursor.getString(cursor.getColumnIndex("time"));long time = Long.parseLong(times);int viewType = cursor.getInt(cursor.getColumnIndex("viewtype"));XmppChat xmppChat = new XmppChat(main, user, nickname, icon, type, content, too, viewType, time);list.add(xmppChat);}cursor.close();}database.close();return list;}public boolean delete(Context context, String too) {boolean isDelete = false;// 1. 在内存中创建数据库帮助类的对象FriendChatOpenHelper helper = new FriendChatOpenHelper(context);// 2. 在磁盘上创建数据库文件SQLiteDatabase database = helper.getWritableDatabase();int d = database.delete("chat", "too = ?", new String[]{too + ""});if (d == 0) {LoggerUtil.systemOut("删除失败");isDelete = false;} else {LoggerUtil.systemOut("删除失败" + too);isDelete = true;}// 释放资源
        database.close();return isDelete;}}

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class FriendChatOpenHelper extends SQLiteOpenHelper {private Context context;public FriendChatOpenHelper(Context context) {super(context, "XMPPChat.db",null,1);}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL("create table chat(id integer primary key autoincrement,main text,user text,nickname text,icon text,type integer,content text,too text,viewtype integer,time text)");}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
}

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import java.util.ArrayList;
import java.util.List;
import cnpc.fcyt.fcydyy.util.LoggerUtil;
import cnpc.fcyt.fcydyy.xmpp.bean.XmppUser;
import cnpc.fcyt.fcydyy.xmpp.bean.XmppMessage;
import cnpc.fcyt.fcydyy.xmpp.util.TimeUtil;public class MessageDao {public Context context;private static MessageDao mInstance;private MessageDao(Context ctx) {this.context = ctx;}public static MessageDao getInstance(Context ctx) {//懒汉: 考虑线程安全问题, 两种方式: 1. 给方法加同步锁 synchronized, 效率低; 2. 给创建对象的代码块加同步锁//读数据不会出现线程安全问题, 写数据会出现线程安全问题//a, B, Cif (mInstance == null) {//B, Csynchronized (MessageDao.class) {//aif (mInstance == null) {mInstance = new MessageDao(ctx);}}}return mInstance;}public List<XmppMessage> queryMessage(Context context,String main ) {// 1. 在内存中创建数据库帮助类的对象MessageOpenHelper helper = new MessageOpenHelper(context);// 2. 在磁盘上创建数据库文件SQLiteDatabase database = helper.getReadableDatabase();Cursor cursor = database.query("message", null, "main = ?", new String[]{main}, null, null, null);ArrayList<XmppMessage> list = new ArrayList<>();while (cursor.moveToNext()) {String type = cursor.getString(cursor.getColumnIndex("type"));int id = cursor.getInt(cursor.getColumnIndex("id"));String to = cursor.getString(cursor.getColumnIndex("too"));String username = cursor.getString(cursor.getColumnIndex("username"));String name = cursor.getString(cursor.getColumnIndex("name"));XmppUser user = new XmppUser(username, name);String time = cursor.getString(cursor.getColumnIndex("time"));String content = cursor.getString(cursor.getColumnIndex("content"));int result = cursor.getInt(cursor.getColumnIndex("result"));XmppMessage xm = new XmppMessage(id, to, type, user, time, content, result, main);list.add(xm);}return list;}public int queryIshas(Context context, String main, String type) {// 1. 在内存中创建数据库帮助类的对象MessageOpenHelper helper = new MessageOpenHelper(context);// 2. 在磁盘上创建数据库文件SQLiteDatabase database = helper.getReadableDatabase();Cursor cursor = database.query("message", null, "main=? and type=?", new String[]{main, type}, null, null, null);if (cursor != null) {if (!cursor.moveToFirst()) {//插入LoggerUtil.systemOut("没有查询到");return -1;} else {//更新LoggerUtil.systemOut("查询到了");int id = cursor.getInt(cursor.getColumnIndex("id"));return id;}} else {LoggerUtil.systemOut("cursor为空");return -1;}}public int queryhasMsg(Context context, String too, String type) {// 1. 在内存中创建数据库帮助类的对象MessageOpenHelper helper = new MessageOpenHelper(context);// 2. 在磁盘上创建数据库文件SQLiteDatabase database = helper.getReadableDatabase();Cursor cursor = database.query("message", null, "too=? and type=?", new String[]{too, type}, null, null, null);if (cursor != null) {if (!cursor.moveToFirst()) {//插入LoggerUtil.systemOut("没有查询到");return -1;} else {//更新LoggerUtil.systemOut("查询到了");int id = cursor.getInt(cursor.getColumnIndex("id"));return id;}} else {LoggerUtil.systemOut("cursor为空");return -1;}}public Cursor queryIshasResult(Context context, String main, String type) {// 1. 在内存中创建数据库帮助类的对象MessageOpenHelper helper = new MessageOpenHelper(context);// 2. 在磁盘上创建数据库文件SQLiteDatabase database = helper.getReadableDatabase();Cursor cursor = database.query("message", null, "main=? and type=?", new String[]{main, type}, null, null, null);if (cursor != null) {if (!cursor.moveToFirst()) {//插入LoggerUtil.systemOut("没有查询到");return null;} else {//更新LoggerUtil.systemOut("查询到了");int result = cursor.getInt(cursor.getColumnIndex("result"));return cursor;}} else {LoggerUtil.systemOut("cursor为空");return null;}}public boolean inserts(Context context, XmppMessage xm) {boolean isSucceed = false;// 1. 在内存中创建数据库帮助类的对象MessageOpenHelper helper = new MessageOpenHelper(context);// 2. 在磁盘上创建数据库文件SQLiteDatabase database = helper.getWritableDatabase();/*** table        :表名* nullColumnHack:*/ContentValues values = new ContentValues();values.put("main", xm.getMain());values.put("name", xm.getUser().getName());values.put("username", xm.getUser().getUserName());values.put("too", xm.getTo());values.put("type", xm.getType());values.put("content", xm.getContent());values.put("time", xm.getTime());values.put("result", xm.getResult());long id = database.insert("message", null, values);if (id == -1) {LoggerUtil.systemOut("插入失败");isSucceed = false;} else {LoggerUtil.systemOut("插入成功");isSucceed = true;}// 释放资源
        database.close();return isSucceed;}public boolean update(Context context, int id, String content, int result) {// 1. 在内存中创建数据库帮助类的对象MessageOpenHelper helper = new MessageOpenHelper(context);// 2. 在磁盘上创建数据库文件SQLiteDatabase database = helper.getWritableDatabase();/*** table        :表名* nullColumnHack:*/ContentValues values = new ContentValues();values.put("content", content);values.put("time", TimeUtil.getDate());values.put("result", result);//返回更新的行数int update = database.update("message", values, "id=?", new String[]{id + ""});database.close();return update > 0;}public boolean updateResult(Context context, String too,String type ,String content) {// 1. 在内存中创建数据库帮助类的对象MessageOpenHelper helper = new MessageOpenHelper(context);// 2. 在磁盘上创建数据库文件SQLiteDatabase database = helper.getWritableDatabase();/*** table        :表名* nullColumnHack:*/ContentValues values = new ContentValues();values.put("result", 0);if (!content.isEmpty()){values.put("content", content);}values.put("time", TimeUtil.getDate());//返回更新的行数int update = database.update("message", values, "too=? and type = ? ", new String[]{too,type});database.close();return update > 0;}public boolean delete(Context context, int id) {boolean isDelete = false;// 1. 在内存中创建数据库帮助类的对象MessageOpenHelper helper = new MessageOpenHelper(context);// 2. 在磁盘上创建数据库文件SQLiteDatabase database = helper.getWritableDatabase();int d = database.delete("message", "id = ?", new String[]{id + ""});if (d == 0) {LoggerUtil.systemOut("删除失败");isDelete = false;} else {LoggerUtil.systemOut("删除失败" + id);isDelete = true;}// 释放资源
        database.close();return isDelete;}
}

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;public class MessageOpenHelper extends SQLiteOpenHelper {private Context context;public MessageOpenHelper(Context context) {super(context, "XMPPMessage.db",null,1);}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL("create table message(id integer primary key autoincrement,main text,too text,name varchar(20),username text,type text,content text,time text,result integer)");}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
}


6.开发过程中,注意注册的用户名和聊天等相关JID的区别,聊天发送的JID需要后缀标识,建群同理,无法与注册用户的JID对应,这点比较无语....


7.项目demo地址下载:https://download.csdn.net/download/jcf0706/10787309


欢迎大家下载学习,对于上面6有啥的好的解决办法,欢迎大家评论或者发邮箱给我建议jcf0706@163.com,一起学习进步!!!


转载于:https://www.cnblogs.com/loaderman/p/9967605.html

用xmmp+openfire+smack搭建简易IM实现相关推荐

  1. Android之基于xmpp openfire smack开发之Android消息推送技术原理分析和实践[4]

    http://blog.csdn.net/shimiso/article/details/8156439 前面几篇给大家系统讲解的有关xmpp openfire smack asmack相关的技术和使 ...

  2. 搭建简易Linux局网服务器

    搭建简易Linux局网服务器 该文章转自 联信软件 作为桌面操作系统,Linux的人机界面可真是不敢恭维,但是,作为网络操作系统,其易用性(对于NOS而言)和高性能恐怕是很难有能出其右的.当然,这并不 ...

  3. Django搭建简易博客

    Django简易博客,主要实现了以下功能 连接数据库 创建超级用户与后台管理 利用django-admin-bootstrap美化界面 template,view与动态URL 多说评论功能 Markd ...

  4. CDH5.15离线搭建简易版集群(完整版)

    运用CDH5.15离线搭建简易版集群 关于CDH和Cloudera CDH(Cloudera的发行版,包括Apache Hadoop),是Hadoop众多分支中的一种,由Cloudera维护,基于稳定 ...

  5. 如何搭建简易又安全的企业内部文件服务器?

    提到搭建企业内部文件服务器,很多人的第一反应是Samba文件服务器. 确实,在过去的很多年里,大部分企业都是通过Windows Server的域控制器使企业内部员工方便地进行资源共享和使用网络打印机. ...

  6. Linux Centos7 搭建简易堡垒机安装jailkit实现chroot

    Linux Centos7 搭建简易堡垒机安装jailkit实现chroot 一.什么是堡垒机 堡垒机,即在一个特定的网络环境下,为了保障网络和数据不受来自外部和内部用户的入侵和破坏,而运用各种技术手 ...

  7. 用 kali 工具 apache 搭建简易网站 LAMP

    搭建简易网站 内网和外网的原理图示: 搭建步骤为LAMP L为linux,A为Apache,M代表Mysql,P代表php ~ 打开apache服务 service apache2 start # 打 ...

  8. iverilog搭建简易仿真平台

    iverilog搭建简易仿真平台 对于xsim和modelsim这种仿真测试平台,对操作系统要求过于严格,为了实现远程verilog编译仿真调试,我选择了linux+iverilog+gtkwave来 ...

  9. 搭建简易的物联网服务端和客户端-Maibu控制(二十一)

    创建麦布应用程序,麦步按键控制.原理和网页控制差不多,就是麦步访问之前创建的两个buttonclick接口.感谢qs100371大神. 代码地址:https://github.com/ZZES-ZVD ...

最新文章

  1. 解决AttributeError: module ‘tensorflow_core._api.v2.config‘ has no attribute ‘experimental_list_device
  2. 每天多一点(2016.12.04)》Javascript隐式转换
  3. websocket导致spring boot 项目单元测试启动失败的问题解决
  4. pytorch图像分类_使用PyTorch和Streamlit创建图像分类Web应用
  5. 洛谷 P4016 负载平衡问题 【最小费用最大流】
  6. iOS coredata 避免添加重复数据
  7. from torchcrf import CRF
  8. mysql中怎么在列中使用时间函数_mysql中关于时间的函数使用教程
  9. PowerDesigner 表名、字段大小写转换
  10. 自下而上分析法基本问题
  11. Android JetPack –导航架构
  12. Swagger 生成 PHP API 接口文档
  13. 记一次西安thoughtworks的面试经历
  14. 毕业论文页码及目录设置方法
  15. 利用jsPDF把图片转成pdf格式保存本地指定目录
  16. 福特汉姆大学计算机科学专业,福特汉姆大学计算机科学排名第131(2018年TFE美国排名)...
  17. 解决导出excel导出名字乱码
  18. Equalize Prices
  19. 厦门商业贷款转公积金攻略
  20. 欧美IT外包的几种业务模式

热门文章

  1. Windows7笔记本正版COA标签辨别
  2. 梦境画成现实,Meta最新AI图像生成工具
  3. SQL UCASE() 函数、SQL LCASE() 函数、SQL MID() 函数
  4. 年终收藏! 一文看尽2020年度最「出圈」AI论文合集
  5. 用php模拟斗地主发牌,网络编程php模拟实现斗地主发牌
  6. 【小月电子】安路国产FPGA开发板系统学习教程-LESSON1点亮LED灯
  7. Shopee物流信息出现问题要怎么查询,你知道吗?
  8. 日立HDS VM存储更换硬盘
  9. APT组织Reaper新Dropper公开:NOKKI和DOGCALL存在关联性
  10. 在Shell或Bat脚本中激活conda环境