zoukankan      html  css  js  c++  java
  • 基于xmpp openfire smack开发之smack类库介绍和使用[2]

    http://blog.csdn.net/shimiso/article/details/8816540

    关于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. });  
     

    SmackTest例子下载

  • 相关阅读:
    对路径“E:AnyWiseUnitBusiXtCalXtCal.SiteMain”的访问被拒绝。
    CentOS Docker 安装
    linux命令检查网络问题
    MYSQL命令(二)
    极简技术简录-HTTP
    Java遍历List、Map的集合方法
    jdbc连接数据库并插入一条带有日期的数据
    MYSQL命令(一)
    JDBC连接MySQL数据库批量插入数据
    观察者模式
  • 原文地址:https://www.cnblogs.com/fx2008/p/4106084.html
Copyright © 2011-2022 走看看