文档章节

基于xmpp openfire smack开发之smack类库介绍和使用[2]

wangjie142
 wangjie142
发布于 2015/02/22 14:32
字数 2796
阅读 62
收藏 1
点赞 1
评论 0

关于Smack编程库,前面我们提到,它是面向Java端的api,主要在PC上使用,利用它我们可以向openfire服务器注册用户,发送消息,并且可以通过监听器获得此用户的应答消息,以及构建聊天室,分组,个人通讯录等等。

下面我们写几个程序小例子测试一下。

(1)登录操作

[java] view plaincopy

  1. PPConnection.DEBUG_ENABLED = true;  

  2. AccountManager accountManager;  

  3. final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(  

  4.         "192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");  

  5.   

  6. // 允许自动连接  

  7. connectionConfig.setReconnectionAllowed(true);  

  8. connectionConfig.setSendPresence(true);  

  9.   

  10. Connection connection = new XMPPConnection(connectionConfig);  

  11. try {  

  12.     connection.connect();// 开启连接  

  13.     accountManager = connection.getAccountManager();// 获取账户管理类  

  14. catch (XMPPException e) {  

  15.     throw new IllegalStateException(e);  

  16. }  

  17.   

  18. // 登录  

  19. connection.login("admin""admin","SmackTest");  

  20. System.out.println(connection.getUser());   

  21. connection.getChatManager().createChat("shimiso@csdn.shimiso.com",null).sendMessage("Hello word!");  

运行结果:

在login中一共有三个参数,登录名,密码,资源名,可能有人不明白资源名到底是什么意思,其实就是客户端的来源,客户端的名称,如果不写它默认就叫smack,如果你用相同的账户不同的资源名和同一个人发三条消息,那将会弹出三个窗口,而不是一个窗口。
同时smack还为我们提供了非常好的调试工具Smack Debug,利用该工具我们可以准确的捕获详细的往返报文信息。

(2)下面我们继续写个聊天的例子:

[java] view plaincopy

  1. PPConnection.DEBUG_ENABLED = true;  

  2. AccountManager accountManager;  

  3. final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(  

  4.         "192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");  

  5.   

  6. // 允许自动连接  

  7. connectionConfig.setReconnectionAllowed(true);  

  8. connectionConfig.setSendPresence(true);  

  9.   

  10. Connection connection = new XMPPConnection(connectionConfig);  

  11. try {  

  12.     connection.connect();// 开启连接  

  13.     accountManager = connection.getAccountManager();// 获取账户管理类  

  14. catch (XMPPException e) {  

  15.     throw new IllegalStateException(e);  

  16. }  

  17.   

  18. // 登录  

  19. connection.login("admin""admin","SmackTest3");    

  20. ChatManager chatmanager = connection.getChatManager();  

  21. Chat newChat = chatmanager.createChat("shimiso@csdn.shimiso.com"new MessageListener() {  

  22.     public void processMessage(Chat chat, Message message) {  

  23.         if (message.getBody() != null) {  

  24.             System.out.println("Received from 【"  

  25.                     + message.getFrom() + "】 message: "  

  26.                     + message.getBody());  

  27.         }  

  28.   

  29.     }  

  30. });  

  31. Scanner input = new Scanner(System.in);  

  32. while (true) {  

  33.     String message = input.nextLine();   

  34.     newChat.sendMessage(message);  

  35. }  

运行结果:

这里我们用Scanner来捕捉用户在控制台的键盘操作,将信息发出,同时创建了一个MessageListener监听,在其中强制实现processMessage方法即可捕获发回的信息,在初次使用上还是较为容易上手的,我们只要细心查看API即可逐步深入下去。

(3)除了聊天以外我们经常还能想到就是广播

需要给所有在线的用户发送一个通知,或者给所有在线和离线的用户全发送,我们先演示如何给在线用户发送一个广播:

[java] view plaincopy

  1. PPConnection.DEBUG_ENABLED = false;  

  2. AccountManager accountManager;  

  3. final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(  

  4.         "192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");  

  5.   

  6. // 允许自动连接  

  7. connectionConfig.setReconnectionAllowed(true);  

  8. connectionConfig.setSendPresence(true);  

  9.   

  10. Connection connection = new XMPPConnection(connectionConfig);  

  11. try {  

  12.     connection.connect();// 开启连接  

  13.     accountManager = connection.getAccountManager();// 获取账户管理类  

  14. catch (XMPPException e) {  

  15.     throw new IllegalStateException(e);  

  16. }  

  17. connection.login("admin""admin","SmackTest3");   

  18. Message newmsg = new Message();   

  19. newmsg.setTo("shimiso@csdn.shimiso.com");  

  20. newmsg.setSubject("重要通知");  

  21. newmsg.setBody("今天下午2点60分有会!");  

  22. newmsg.setType(Message.Type.headline);// normal支持离线   

  23. connection.sendPacket(newmsg);  

  24. connection.disconnect();  

运行结果:

将参数设置为Message.Type.normal即可支持离线广播,openfire系统会自动判断该用户是否在线,如果在线就直接发送出去,如果不在线则将信息存入ofoffline表,现在我将shimiso用户退出登录,再给它发消息,我们可以进入openfire库的ofoffline表中,非常清楚看到里面躺着一条离线消息记录是发给shimiso这个用户的

(4)那么我们如何让shimiso这个用户一登陆就取到离线消息呢?

请看如下代码

[java] view plaincopy

  1. PPConnection.DEBUG_ENABLED = false;  

  2. AccountManager accountManager;  

  3. final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(  

  4.         "192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");  

  5.   

  6. // 允许自动连接  

  7. connectionConfig.setReconnectionAllowed(true);  

  8. connectionConfig.setSendPresence(false);//不要告诉服务器自己的状态  

  9. Connection connection = new XMPPConnection(connectionConfig);  

  10. try {  

  11.     connection.connect();// 开启连接  

  12.     accountManager = connection.getAccountManager();// 获取账户管理类  

  13. catch (XMPPException e) {  

  14.     throw new IllegalStateException(e);  

  15. }   

  16. connection.login("shimiso""123","SmackTest");   

  17. OfflineMessageManager offlineManager = new OfflineMessageManager(  

  18.         connection);  

  19. try {  

  20.     Iterator<org.jivesoftware.smack.packet.Message> it = offlineManager  

  21.             .getMessages();  

  22.   

  23.     System.out.println(offlineManager.supportsFlexibleRetrieval());  

  24.     System.out.println("离线消息数量: " + offlineManager.getMessageCount());  

  25.   

  26.     Map<String, ArrayList<Message>> offlineMsgs = new HashMap<String, ArrayList<Message>>();  

  27.   

  28.     while (it.hasNext()) {  

  29.         org.jivesoftware.smack.packet.Message message = it.next();  

  30.         System.out  

  31.                 .println("收到离线消息, Received from 【" + message.getFrom()  

  32.                         + "】 message: " + message.getBody());  

  33.         String fromUser = message.getFrom().split("/")[0];  

  34.   

  35.         if (offlineMsgs.containsKey(fromUser)) {  

  36.             offlineMsgs.get(fromUser).add(message);  

  37.         } else {  

  38.             ArrayList<Message> temp = new ArrayList<Message>();  

  39.             temp.add(message);  

  40.             offlineMsgs.put(fromUser, temp);  

  41.         }  

  42.     }  

  43.   

  44.     // 在这里进行处理离线消息集合......  

  45.     Set<String> keys = offlineMsgs.keySet();  

  46.     Iterator<String> offIt = keys.iterator();  

  47.     while (offIt.hasNext()) {  

  48.         String key = offIt.next();  

  49.         ArrayList<Message> ms = offlineMsgs.get(key);  

  50.   

  51.         for (int i = 0; i < ms.size(); i++) {  

  52.             System.out.println("-->" + ms.get(i));  

  53.         }  

  54.     }  

  55.   

  56.     offlineManager.deleteMessages();  

  57. catch (Exception e) {  

  58.     e.printStackTrace();  

  59. }  

  60. offlineManager.deleteMessages();//删除所有离线消息  

  61. Presence presence = new Presence(Presence.Type.available);  

  62.             nnection.sendPacket(presence);//上线了  

  63.             nnection.disconnect();//关闭连接  

运行结果:

这里我们需要特别当心的是先不要告诉openfire服务器你上线了,否则永远也拿不到离线消息,用下面英文大概意思就是在你上线之前去获取离线消息,这么设计是很有道理的。

The OfflineMessageManager helps manage offline messages even before the user has sent an available presence. When a user asks for his offline messages before sending an available presence then the server will not send a flood with all the offline messages when the user becomes online. The server will not send a flood with all the offline messages to the session that made the offline messages request or to any other session used by the user that becomes online.

拿到离线消息处理完毕之后删除离线消息offlineManager.deleteMessages() 接着通知服务器上线了。

(5)下面我们来看看如何来发送文件

[java] view plaincopy

  1. PPConnection.DEBUG_ENABLED = false;  

  2. AccountManager accountManager;  

  3. final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(  

  4.         "192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");  

  5.   

  6. // 允许自动连接  

  7. connectionConfig.setReconnectionAllowed(true);  

  8. connectionConfig.setSendPresence(true);  

  9.   

  10. Connection connection = new XMPPConnection(connectionConfig);  

  11. try {  

  12.     connection.connect();// 开启连接  

  13.     accountManager = connection.getAccountManager();// 获取账户管理类  

  14. catch (XMPPException e) {  

  15.     throw new IllegalStateException(e);  

  16. }  

  17.   connection.login("admin""admin","Rooyee");   

  18.   Presence pre = connection.getRoster().getPresence("shimiso@csdn.shimiso.com");  

  19.     System.out.println(pre);  

  20.     if (pre.getType() != Presence.Type.unavailable) {  

  21.         // 创建文件传输管理器  

  22.         FileTransferManager manager = new FileTransferManager(connection);  

  23.         // 创建输出的文件传输  

  24.         OutgoingFileTransfer transfer = manager  

  25.                 .createOutgoingFileTransfer(pre.getFrom());  

  26.         // 发送文件  

  27.         transfer.sendFile(new File("E:\\Chrysanthemum.jpg"), "图片");  

  28.         while (!transfer.isDone()) {  

  29.             if (transfer.getStatus() == FileTransfer.Status.in_progress) {  

  30.                 // 可以调用transfer.getProgress();获得传输的进度   

  31.                 System.out.println(transfer.getStatus());  

  32.                 System.out.println(transfer.getProgress());  

  33.                 System.out.println(transfer.isDone());  

  34.             }  

  35.         }  

  36.     }  

运行结果:

在这里我们需要特别注意的是,跨资源是无法发送文件的,看connection.login("admin", "admin","Rooyee");这个代码就明白了,必须是“域名和资源名”完全相同的两个用户才可以互发文件,否则永远都没反应,如果不清楚自己所用的客户端的资源名,可以借助前面提到的SmackDebug工具查看往返信息完整报文,在to和from中一定可以看到。

如果我们自己要写文件接收例子的话,参考代码如下:

[java] view plaincopy

  1. FileTransferManager transfer = new FileTransferManager(connection);  

  2. transfer.addFileTransferListener(new RecFileTransferListener());  

  3. public class RecFileTransferListener implements FileTransferListener {  

  4.   

  5.     public String getFileType(String fileFullName) {  

  6.         if (fileFullName.contains(".")) {  

  7.             return "." + fileFullName.split("//.")[1];  

  8.         } else {  

  9.             return fileFullName;  

  10.         }  

  11.   

  12.     }  

  13.   

  14.     @Override  

  15.     public void fileTransferRequest(FileTransferRequest request) {  

  16.         System.out.println("接收文件开始.....");  

  17.         final IncomingFileTransfer inTransfer = request.accept();  

  18.         final String fileName = request.getFileName();  

  19.         long length = request.getFileSize();  

  20.         final String fromUser = request.getRequestor().split("/")[0];  

  21.         System.out.println("文件大小:" + length + "  " + request.getRequestor());  

  22.         System.out.println("" + request.getMimeType());  

  23.         try {  

  24.   

  25.             JFileChooser chooser = new JFileChooser();  

  26.             chooser.setCurrentDirectory(new File("."));  

  27.   

  28.             int result = chooser.showOpenDialog(null);  

  29.   

  30.             if (result == JFileChooser.APPROVE_OPTION) {  

  31.                 final File file = chooser.getSelectedFile();  

  32.                 System.out.println(file.getAbsolutePath());  

  33.                 new Thread() {  

  34.                     public void run() {  

  35.                         try {  

  36.   

  37.                             System.out.println("接受文件: " + fileName);  

  38.                             inTransfer  

  39.                                     .recieveFile(new File(file  

  40.                                             .getAbsolutePath()  

  41.                                             + getFileType(fileName)));  

  42.   

  43.                             Message message = new Message();  

  44.                             message.setFrom(fromUser);  

  45.                             message.setProperty("REC_SIGN""SUCCESS");  

  46.                             message.setBody("[" + fromUser + "]发送文件: "  

  47.                                     + fileName + "/r/n" + "存储位置: "  

  48.                                     + file.getAbsolutePath()  

  49.                                     + getFileType(fileName));  

  50.                             if (Client.isChatExist(fromUser)) {  

  51.                                 Client.getChatRoom(fromUser)  

  52.                                         .messageReceiveHandler(message);  

  53.                             } else {  

  54.                                 ChatFrameThread cft = new ChatFrameThread(  

  55.                                         fromUser, message);  

  56.                                 cft.start();  

  57.   

  58.                             }  

  59.                         } catch (Exception e2) {  

  60.                             e2.printStackTrace();  

  61.                         }  

  62.                     }  

  63.                 }.start();  

  64.             } else {  

  65.   

  66.                 System.out.println("拒绝接受文件: " + fileName);  

  67.   

  68.                 request.reject();  

  69.                 Message message = new Message();  

  70.                 message.setFrom(fromUser);  

  71.                 message.setBody("拒绝" + fromUser + "发送文件: " + fileName);  

  72.                 message.setProperty("REC_SIGN""REJECT");  

  73.                 if (Client.isChatExist(fromUser)) {  

  74.                     Client.getChatRoom(fromUser).messageReceiveHandler(message);  

  75.                 } else {  

  76.                     ChatFrameThread cft = new ChatFrameThread(fromUser, message);  

  77.                     cft.start();  

  78.                 }  

  79.             }  

  80.   

  81.             /* 

  82.              * InputStream in = inTransfer.recieveFile(); 

  83.              *  

  84.              * String fileName = "r"+inTransfer.getFileName(); 

  85.              *  

  86.              * OutputStream out = new FileOutputStream(new 

  87.              * File("d:/receive/"+fileName)); byte[] b = new byte[512]; 

  88.              * while(in.read(b) != -1) { out.write(b); out.flush(); } 

  89.              *  

  90.              * in.close(); out.close(); 

  91.              */  

  92.         } catch (Exception e) {  

  93.             e.printStackTrace();  

  94.         }  

  95.   

  96.         System.out.println("接收文件结束.....");  

  97.   

  98.     }  

  99.   

  100. }  

(6)用户列表

[java] view plaincopy

  1. **  

  2.  * 返回所有组信息 <RosterGroup>  

  3.  *   

  4.  * @return List(RosterGroup)  

  5.  */  

  6. public static List<RosterGroup> getGroups(Roster roster) {  

  7.     List<RosterGroup> groupsList = new ArrayList<RosterGroup>();  

  8.     Collection<RosterGroup> rosterGroup = roster.getGroups();  

  9.     Iterator<RosterGroup> i = rosterGroup.iterator();  

  10.     while (i.hasNext())  

  11.         groupsList.add(i.next());  

  12.     return groupsList;  

  13. }  

  14.   

  15. /** 

  16.  * 返回相应(groupName)组里的所有用户<RosterEntry> 

  17.  *  

  18.  * @return List(RosterEntry) 

  19.  */  

  20. public static List<RosterEntry> getEntriesByGroup(Roster roster,  

  21.         String groupName) {  

  22.     List<RosterEntry> EntriesList = new ArrayList<RosterEntry>();  

  23.     RosterGroup rosterGroup = roster.getGroup(groupName);  

  24.     Collection<RosterEntry> rosterEntry = rosterGroup.getEntries();  

  25.     Iterator<RosterEntry> i = rosterEntry.iterator();  

  26.     while (i.hasNext())  

  27.         EntriesList.add(i.next());  

  28.     return EntriesList;  

  29. }  

  30.   

  31. /** 

  32.  * 返回所有用户信息 <RosterEntry> 

  33.  *  

  34.  * @return List(RosterEntry) 

  35.  */  

  36. public static List<RosterEntry> getAllEntries(Roster roster) {  

  37.     List<RosterEntry> EntriesList = new ArrayList<RosterEntry>();  

  38.     Collection<RosterEntry> rosterEntry = roster.getEntries();  

  39.     Iterator<RosterEntry> i = rosterEntry.iterator();  

  40.     while (i.hasNext())  

  41.         EntriesList.add(i.next());  

  42.     return EntriesList;  

  43. }  

(7)用户头像的获取

使用VCard,很强大,具体自己看API吧,可以看看VCard传回来XML的组成,含有很多信息的

[java] view plaincopy

  1. **  

  2.  * 获取用户的vcard信息  

  3.  * @param connection  

  4.  * @param user  

  5.  * @return  

  6.  * @throws XMPPException  

  7.  */  

  8. public static VCard getUserVCard(XMPPConnection connection, String user) throws XMPPException  

  9. {  

  10.     VCard vcard = new VCard();  

  11.     vcard.load(connection, user);  

  12.       

  13.     return vcard;  

  14. }  

  15.   

  16. /** 

  17.  * 获取用户头像信息 

  18.  */  

  19. public static ImageIcon getUserImage(XMPPConnection connection, String user) {  

  20.     ImageIcon ic = null;  

  21.     try {  

  22.         System.out.println("获取用户头像信息: "+user);  

  23.         VCard vcard = new VCard();  

  24.         vcard.load(connection, user);  

  25.           

  26.         if(vcard == null || vcard.getAvatar() == null)  

  27.         {  

  28.             return null;  

  29.         }  

  30.         ByteArrayInputStream bais = new ByteArrayInputStream(  

  31.                 vcard.getAvatar());  

  32.         Image image = ImageIO.read(bais);  

  33.   

  34.           

  35.         ic = new ImageIcon(image);  

  36.         System.out.println("图片大小:"+ic.getIconHeight()+" "+ic.getIconWidth());  

  37.       

  38.     } catch (Exception e) {  

  39.         e.printStackTrace();  

  40.     }  

  41.     return ic;  

  42. }  

(8)组操作和用户分组操作

[java] view plaincopy

  1. **  

  2.  * 添加一个组  

  3.  */  

  4. public static boolean addGroup(Roster roster,String groupName)  

  5. {  

  6.     try {  

  7.         roster.createGroup(groupName);  

  8.         return true;  

  9.     } catch (Exception e) {  

  10.         e.printStackTrace();  

  11.         return false;  

  12.     }  

  13. }  

  14.   

  15. /** 

  16.  * 删除一个组 

  17.  */  

  18. public static boolean removeGroup(Roster roster,String groupName)  

  19. {  

  20.     return false;  

  21. }  

  22.   

  23. /** 

  24.  * 添加一个好友  无分组 

  25.  */  

  26. public static boolean addUser(Roster roster,String userName,String name)  

  27. {  

  28.     try {  

  29.         roster.createEntry(userName, name, null);  

  30.         return true;  

  31.     } catch (Exception e) {  

  32.         e.printStackTrace();  

  33.         return false;  

  34.     }  

  35. }  

  36. /** 

  37.  * 添加一个好友到分组 

  38.  * @param roster 

  39.  * @param userName 

  40.  * @param name 

  41.  * @return 

  42.  */  

  43. public static boolean addUser(Roster roster,String userName,String name,String groupName)  

  44. {  

  45.     try {  

  46.         roster.createEntry(userName, name,new String[]{ groupName});  

  47.         return true;  

  48.     } catch (Exception e) {  

  49.         e.printStackTrace();  

  50.         return false;  

  51.     }  

  52. }  

  53.   

  54. /** 

  55.  * 删除一个好友 

  56.  * @param roster 

  57.  * @param userName 

  58.  * @return 

  59.  */  

  60. public static boolean removeUser(Roster roster,String userName)  

  61. {  

  62.     try {  

  63.           

  64.         if(userName.contains("@"))  

  65.         {  

  66.             userName = userName.split("@")[0];  

  67.         }  

  68.         RosterEntry entry = roster.getEntry(userName);  

  69.         System.out.println("删除好友:"+userName);  

  70.         System.out.println("User: "+(roster.getEntry(userName) == null));  

  71.         roster.removeEntry(entry);  

  72.           

  73.         return true;  

  74.     } catch (Exception e) {  

  75.         e.printStackTrace();  

  76.         return false;  

  77.     }  

  78.       

  79. }  

(9)用户查询

[java] view plaincopy

  1. public static List<UserBean> searchUsers(XMPPConnection connection,String serverDomain,String userName) throws XMPPException  

  2.     {  

  3.         List<UserBean> results = new ArrayList<UserBean>();  

  4.         System.out.println("查询开始..............."+connection.getHost()+connection.getServiceName());  

  5.           

  6.         UserSearchManager usm = new UserSearchManager(connection);  

  7.           

  8.           

  9.         Form searchForm = usm.getSearchForm(serverDomain);  

  10.         Form answerForm = searchForm.createAnswerForm();  

  11.         answerForm.setAnswer("Username"true);  

  12.         answerForm.setAnswer("search", userName);  

  13.         ReportedData data = usm.getSearchResults(answerForm, serverDomain);  

  14.            

  15.          Iterator<Row> it = data.getRows();  

  16.          Row row = null;  

  17.          UserBean user = null;  

  18.          while(it.hasNext())  

  19.          {  

  20.              user = new UserBean();  

  21.              row = it.next();  

  22.              user.setUserName(row.getValues("Username").next().toString());  

  23.              user.setName(row.getValues("Name").next().toString());  

  24.              user.setEmail(row.getValues("Email").next().toString());  

  25.              System.out.println(row.getValues("Username").next());  

  26.              System.out.println(row.getValues("Name").next());  

  27.              System.out.println(row.getValues("Email").next());  

  28.              results.add(user);  

  29.              //若存在,则有返回,UserName一定非空,其他两个若是有设,一定非空  

  30.          }  

  31.            

  32.          return results;  

  33.     }  

(10)修改自身状态

包括上线,隐身,对某人隐身,对某人上线

[java] view plaincopy

  1. ublic static void updateStateToAvailable(XMPPConnection connection)  

  2. {  

  3.     Presence presence = new Presence(Presence.Type.available);  

  4.             nnection.sendPacket(presence);  

  5.           

  6.   

  7. public static void updateStateToUnAvailable(XMPPConnection connection)  

  8. {  

  9.     Presence presence = new Presence(Presence.Type.unavailable);  

  10.             nnection.sendPacket(presence);  

  11.     }  

  12.   

  13. public static void updateStateToUnAvailableToSomeone(XMPPConnection connection,String userName)  

  14. {  

  15.     Presence presence = new Presence(Presence.Type.unavailable);  

  16.     presence.setTo(userName);  

  17.             nnection.sendPacket(presence);  

  18. }  

  19. public static void updateStateToAvailableToSomeone(XMPPConnection connection,String userName)  

  20. {  

  21.     Presence presence = new Presence(Presence.Type.available);  

  22.     presence.setTo(userName);  

  23.             nnection.sendPacket(presence);  

  24.   

  25. }  

(11)心情修改

[java] view plaincopy

  1. **  

  2.  * 修改心情  

  3.  * @param connection  

  4.  * @param status  

  5.  */  

  6. public static void changeStateMessage(XMPPConnection connection,String status)  

  7. {  

  8.     Presence presence = new Presence(Presence.Type.available);  

  9.     presence.setStatus(status);  

  10.     connection.sendPacket(presence);  

  11.   

  12. }  

(12)修改用户头像

有点麻烦,主要是读入图片文件,编码,传输之

[java] view plaincopy

  1. public static void changeImage(XMPPConnection connection,File f) throws XMPPException, IOException{  

  2.       

  3.         VCard vcard = new VCard();  

  4.         vcard.load(connection);  

  5.           

  6.             byte[] bytes;  

  7.             

  8.                 bytes = getFileBytes(f);  

  9.                 String encodedImage = StringUtils.encodeBase64(bytes);  

  10.                 vcard.setAvatar(bytes, encodedImage);  

  11.                 vcard.setEncodedImage(encodedImage);  

  12.                 vcard.setField("PHOTO""<TYPE>image/jpg</TYPE><BINVAL>"  

  13.                         + encodedImage + "</BINVAL>"true);  

  14.                   

  15.                   

  16.                 ByteArrayInputStream bais = new ByteArrayInputStream(  

  17.                         vcard.getAvatar());  

  18.                 Image image = ImageIO.read(bais);  

  19.                 ImageIcon ic = new ImageIcon(image);  

  20.                    

  21.              

  22.             

  23.             vcard.save(connection);  

  24.              

  25.     }  

  26.       

  27.       private static byte[] getFileBytes(File file) throws IOException {  

  28.                 BufferedInputStream bis = null;  

  29.             try {  

  30.             bis = new BufferedInputStream(new FileInputStream(file));  

  31.             int bytes = (int) file.length();  

  32.             byte[] buffer = new byte[bytes];  

  33.             int readBytes = bis.read(buffer);  

  34.             if (readBytes != buffer.length) {  

  35.                 throw new IOException("Entire file not read");  

  36.             }  

  37.             return buffer;  

  38.         } finally {  

  39.             if (bis != null) {  

  40.                 bis.close();  

  41.             }  

  42.         }  

  43. }  

(13)用户状态的监听

即对方改变头像,状态,心情时,更新自己用户列表,其实这里已经有smack实现的监听器

[java] view plaincopy

  1. nal Roster roster = Client.getRoster();  

  2.   

  3. roster.addRosterListener(  

  4.     new RosterListener() {  

  5.   

  6.             @Override  

  7.             public void entriesAdded(Collection<String> arg0) {  

  8.                 // TODO Auto-generated method stub  

  9.                 System.out.println("--------EE:"+"entriesAdded");  

  10.             }  

  11.   

  12.             @Override  

  13.             public void entriesDeleted(Collection<String> arg0) {  

  14.                 // TODO Auto-generated method stub  

  15.                 System.out.println("--------EE:"+"entriesDeleted");  

  16.             }  

  17.   

  18.             @Override  

  19.             public void entriesUpdated(Collection<String> arg0) {  

  20.                 // TODO Auto-generated method stub  

  21.                 System.out.println("--------EE:"+"entriesUpdated");  

  22.             }  

  23.   

  24.             @Override  

  25.             public void presenceChanged(Presence arg0) {  

  26.                 // TODO Auto-generated method stub  

  27.                 System.out.println("--------EE:"+"presenceChanged");  

  28.             }     

  29.               

  30. });  


本文转载自:http://blog.csdn.net/shimiso/article/details/8816540

共有 人打赏支持
wangjie142
粉丝 5
博文 12
码字总数 7731
作品 0
无锡
程序员
XMPP客户端库Smack 4.0.6版开发之一

一、Smack库概述 Smack是一个开源、易用的XMPP/Jabber客户端库,它使用Java语言开发,由Jive Software开发。 Smack的优点是编程简单。 Smack的缺点是其API并非为大量并发用户设计,每个客户都...

今幕明
2015/03/31
0
3
Android asmack使用介绍

XMPP协议简介 XMPP协议(Extensible Messaging and PresenceProtocol,可扩展消息处理现场协议)是一种基于XML的协议,目的是为了解决及时通信标准而提出来的,最早是在Jabber上实现的。它继...

让代码飞一会
2015/07/10
0
0
Smack 4.1.0 RC3/Smack 4.2.0 Alpha 发布

Smack 是一个开源,易于使用的XMPP(jabber)的 Java 客户端类库。 Ignite Realtime 社区现在作为 XMPP Standards Foundation (XSF) GSOC organization 中的一员,参与了 Google Summer of C...

oschina
2015/03/10
1K
5
OpenFire、Spark、Smack介绍

OpenFire 是采用Java开发的基于XMPP(Jabber)协议,开源实时协作(RTC)服务器。 Smack 是用 Java编 写的XMPP客户端代码库,是 spark 的核心 开源界总是有许多有趣的东东,这三个合起来就是...

长平狐
2013/01/06
1K
0
Smack 4.1.0-alpha1 发布,XMPP 客户端开发包

Smack 4.1.0-alpha1 发布,此版本在 Smack 再开发历史上是个里程碑版本,因为是在 Android 上本地运行的第一个版本,这意味着 aSmack 不再是必须的,未来将会被淘汰,作为为 4.0 稳定版本的固...

oschina
2014/09/14
5.2K
5
【openfire,smack使用总结】--Smack库的使用

Smack介绍 Smack是XMPP协议的的实现库,Smack库易于使用,仅仅几行代码就能实现客户端连接,登陆,发送即时消息。但是由于使用XMPP协议,所以不适合用在高并发的场合。 Smack的使用 本文使用...

e_one
2017/03/09
0
0
Smack 4.2.4 发布,开源 XMPP 客户端库

Smack 4.2.4 已发布,Smack 是一个开源,易于使用的 XMPP(jabber) 的 Java 客户端类库,Smack 的 patchlevel 版本与 API 兼容。 Bug [SMACK-804] - ServiceAdministrationManager does not ...

周其
04/17
0
0
Smack 4.1.7 和 4.2.0-beta1 发布

Smack 4.1.7 和 4.2.0-beta1 发布了。Smack是一个开源,易于使用的XMPP(jabber)的 Java 客户端类库。 改进记录如下: [SMACK-712] - XMPPTCPConnection's setEnabledSSL(Protocols|Cipher...

oschina
2016/04/16
2.2K
0
Smack 4.1.8 和 4.2.0-beta2 发布

Smack 4.1.8 和 4.2.0-beta2 发布了。Smack是一个开源,易于使用的XMPP(jabber)的 Java 客户端类库。 Smack 4.1.8修复了几个小问题,预计将是4.1分支的最后一个版本。 更新内容: [SMACK-7...

oschina
2016/07/31
913
0
Smack 4.1.0 发布,XMPP 开发包

Smack 4.1.0 发布,此版本主要修改信息如下: [SMACK-65] - Packet parsing should look for depth [SMACK-237] - Handle more vCard values (XEP-0054) [SMACK-383] - Allow the garbage co......

oschina
2015/03/30
2K
3

没有更多内容

加载失败,请刷新页面

加载更多

下一页

spring boot中swagger2使用

1.pom.xml中添加 <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version>......

说回答
9分钟前
0
0
tomcat虚拟路径的几种配置方法

tomcat虚拟路径的几种配置方法 一般我们都是直接引用webapps下面的web项目,如果我们要部署一个在其它地方的WEB项目,这就要在TOMCAT中设置虚拟路径了,Tomcat的加载web顺序是先加载 $Tomcat_ho...

Helios51
21分钟前
1
0
Mac 安装jupyter notebook的过程

MAC台式机 python:mac下自带Python 2.7.10 1.先升级了pip安装工具:sudo python -m pip install --upgrade --force pip 2.安装setuptools 工具:sudo pip install setuptools==33.1.1 3.安装......

火力全開
27分钟前
0
0
导航守卫解释与例子

“导航”表示路由正在发生改变。 正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。 记住...

tianyawhl
27分钟前
0
0
Java日志框架-logback配置文件多环境日志配置(开发、测试、生产)(原始解决方法)

说明:这种方式应该算是最通用的,原理是通过判断标签实现。 <!-- if-then form --> <if condition="some conditional expression"> <then> ... </then> </if> ......

浮躁的码农
41分钟前
1
0
FTP传输时的两种登录方式和区别

登录方式 匿名登录 用户名为: anonymous。 密码为:任何合法 email 地址。 授权登录 用户名为:用户在远程系统中的用户帐号。 密码为:用户在远程系统中的用户密码。 区别 匿名登录 只能访问...

寰宇01
42分钟前
0
0
plsql developer 配置监听(不安装oracle客户端)

plsql developer 配置监听(不安装oracle客户端)

微小宝
49分钟前
1
0
数据库(分库分表)中间件对比

本人的宗旨就是,能copy的,绝对不手写。 分区:对业务透明,分区只不过把存放数据的文件分成了许多小块,例如mysql中的一张表对应三个文件.MYD,MYI,frm。 根据一定的规则把数据文件(MYD)和索...

奔跑吧代码
53分钟前
2
0
Netty与Reactor模式详解

在学习Reactor模式之前,我们需要对“I/O的四种模型”以及“什么是I/O多路复用”进行简单的介绍,因为Reactor是一个使用了同步非阻塞的I/O多路复用机制的模式。 I/O的四种模型 I/0 操作 主要...

hutaishi
59分钟前
1
0
【2018.07.16学习笔记】【linux高级知识 20.16-20.19】

20.16/20.17 shell中的函数 20.18 shell中的数组 20.19 告警系统需求分析

lgsxp
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部