Simple IM Chat program
because the project needs to do a XMPP protocol based on the Android communication software. So began to study XMPP.
The XMPP protocol uses the client-server architecture, all messages and data sent from one client to another must be forwarded by the XMPP server, and the routing of DNS between servers is supported, which means that the server cluster can be built so that different
The client can also communicate under the server, the predecessor of XMPP is a network communication protocol developed by an open source organization--JABBER,XMPP is the protocol that sends the XML stream on the network fragment, this protocol is XMPP's instant communication instruction transmission means.
In order to prevent data being tampered or overheard between servers, XMPP server communication introduces the TLS mechanism and uses TLS to encrypt data so as to ensure the security of data in the process of transmission.
The address of a XMPP entity is called Jabber identifier or Jid, which acts like an IP address. A valid Jid includes the node name, the domain name resource name, and the format is: Jid=[node ' @ ']domain['/' resource '
Namespace for the XMPP protocol:
- Jabber:iq:private-Private data store, for local user private settings information, such as user notes.
- Jabber:iq:conference-General Meeting for information sharing among multiple users
- Jabber:x:encrypted--an encrypted message used to send an encrypted message
- Jabber:x:expire--Message terminated
- Jabber:iq:time--Client time
- Jabber:iq:auth-Simple user authentication, typically used for authentication between servers or between servers and clients
- Jabber:x:roster--Internal roster
- Jabber:x:signed--Online status of the mark
- Jabber:iq:search--User database query for sending query requests to the server
- Jabber:iq:register--Registration request, for user registration related information
- Jabber:x:iq:roster--roster management
- Jabber:x:conference--A meeting invitation to send a meeting notification to the participating users
- Jabber:x:event--Message events
- Vcard-temp-A temporary vcard used to set the user's avatar and nickname, etc.
In search of the Internet, there are open source projects Beem, open source XMPP framework for Android Asmack,asmack is the smack version of Android. Now start learning smack
。 XMPP is God horse things, no nonsense. First in the online next OpenFire and Spack, do not know what these two things, directly google it. Install openfire need MySQL support, of course, Oracle,sqlserver certainly can. Let's go ahead and figure it out:
OpenFire + Spark + myxmppp
Import Java.io.InputStreamReader;
Import java.util.Collection;
Import Org.jivesoftware.smack.Chat;
Import Org.jivesoftware.smack.ChatManager;
Import Org.jivesoftware.smack.ChatManagerListener;
Import org.jivesoftware.smack.ConnectionConfiguration;
Import Org.jivesoftware.smack.MessageListener;
Import Org.jivesoftware.smack.PrivacyListManager;
Import Org.jivesoftware.smack.Roster;
Import Org.jivesoftware.smack.RosterEntry;
Import Org.jivesoftware.smack.RosterGroup;
Import Org.jivesoftware.smack.RosterListener;
Import org.jivesoftware.smack.XMPPConnection;
Import Org.jivesoftware.smack.packet.Message;
Import org.jivesoftware.smack.packet.Presence;
public class Testsmack {public static void main (string[] args) {xmppconnection.debug_enabled = true; My Computer ip:10.16.25.90 final connectionconfiguration connectionconfig = new Connectionconfiguration ("10.16.25.91", 5222
, "");
Connectionconfig.setsaslauthenticationenabled (FALSE);
try { Xmppconnection connection = new Xmppconnection (connectionconfig); Connection.connect ();//Connect Connection.login ("test", "test");//Login System.out.println (connection.getuse
R ());
Chatmanager Chatmanager = Connection.getchatmanager (); Create a new session Chat Newchat = Chatmanager.createchat ("test3@pc2010102716", new MessageListener () {Publi c void ProcessMessage (Chat Chat, message message) {SYSTEM.OUT.PRINTLN ("Received from" "+ Message.getfrom" (
+ "" Message: "+ message.getbody ());
}
});
Listen for passive receive messages, or broadcast message listener Chatmanager.addchatlistener (new Chatmanagerlistener () {@Override public void chatcreated (Chat Chat, Boolean createdlocally) {Chat.addmessagelistener (New MessageListener (
{@Override public void ProcessMessage (Chat Chat) { SYstem.out.println ("Received from" "+ message.getfrom () +" "Message:" + message.getbody ());
}
});
}
});
Send a message newchat.sendmessage ("I am a rookie");
Get roster ROSTER roster = Connection.getroster ();
collection<rosterentry> entries = Roster.getentries (); for (Rosterentry entry:entries) {System.out.print (Entry.getname () + "-" + entry.getuser () + "-" + entry
. GetType () + "-" + entry.getgroups (). Size ());
Presence Presence = roster.getpresence (Entry.getuser ());
System.out.println ("-" + presence.getstatus () + "-" + Presence.getfrom ());
//Add a roster listener to monitor the change of buddy status. Roster.addrosterlistener (New Rosterlistener () {@Override public void entriesadded (collection& Lt String> addresses) {System.out.println ("entriesadded"); @Override public void entriesupdated (collection<string> addresses) {Sy
Stem.out.println ("entriesupdated"); @Override public void entriesdeleted (collection<string> addresses) {Sy
Stem.out.println ("entriesdeleted"); @Override public void presencechanged (Presence Presence) {System.out.println
("presencechanged->" + presence.getstatus ());
}
});
Create Group///rostergroup group = Roster.creategroup ("university");
for (Rosterentry entry:entries) {//Group.addentry (entry);
For (Rostergroup g:roster.getgroups ()) {for (Rosterentry entry:g.getentries ()) { System.out.println ("Group" +g.getname () + ">>" + entry.getname () + "-" + entry.getuser () + "-" + Entry.GetType () + "-" + entry.getgroups (). Size ()); }//Send message BufferedReader Cmdin = new BufferedReader (New InputStreamReader (Sy
stem.in));
while (true) {try {String cmd = Cmdin.readline ();
if ("!q". Equalsignorecase (cmd)) {break;
} newchat.sendmessage (cmd);
}catch (Exception ex) {}} connection.disconnect ();
System.exit (0);
catch (Exception e) {e.printstacktrace ();
}
}
}
If the code above is running on General Java project and needs to join Smack.jar and Klmx2.jar, if it's Android project, the base code doesn't need to change, just put it into oncreate (...) method, you need to join the Asmack.jar package.
1, Connectionconfiguration
As the configuration used to establish a connection with the XMPP service. It can configure whether the connection uses TLS,SASL encryption.
Include inline classes: Connectionconfiguration.securitymode
2, Xmppconnection.
Xmppconnection This class is used to connect the XMPP service.
You can use the Connect () method to establish a connection to the server. The disconnect () method disconnects from the server.
You can use xmppconnection.debug_enabled = true before creating a connection; Enables the development process to pop up a GUI window to display our connection and send packet information.
3, Chatmanager
Used to monitor all current chat. You can create a chat using Createchat (String Userjid, MessageListener Listener).
4, Chat
Chat is used to monitor a series of message between two users. Using Addmessagelistener (MessageListener listener) will trigger listener ProcessMessage (Chat Chat, message messages) when any information arrives
Method.
We can send a message using SendMessage (), which has two overloaded methods, a string type for arguments of a class type, and an incoming messages object (described later).
So is there a situation in which we can receive messages when someone takes the initiative to set up a connection to send a message, or when the system sends a message?
That's what I'm doing now:
Chatmanager.addchatlistener (New Chatmanagerlistener () {
@Override public
void chatcreated (Chat Chat, Boolean createdlocally) {
Chat.addmessagelistener (new MessageListener () {
@Override public
void ProcessMessage ( Chat Chat, Message message) {
System.out.println ("Received message:" + message.getbody ());
}
);
}
});
5, message
The
- message is used to represent a message pack (you can use the debugging tools to see the contents of the sending and receiving packages). It has many of the following types.
- Message.Type.NORMAL--(default) text messages (such as messages)
- Message.Type.CHAT--typical short messages, such as messages displayed on one line of QQ chat
- Message.Type.GROUP_CHAT--group chat message
- Message.Type.HEADLINE--scrolling message
- MESSAG E.type. Error--Wrong message
- message has two internal classes:
- Message.body--representing the message body
- message.type--table Shows the message type
6, Roster
represents a roster of many rosterentry. For ease of management, the roster's entries are decibels to each group.
You can use Connection.getroster () to get the Roster object when a connection to the XMPP service is established.
Other users can use a subscription request (equivalent to QQ plus friends) to try to subscribe to the destination user. These requests can be processed using the values of the enumeration type Roster.subscriptionmode:
accept_all: Receive all subscription requests
reject_all: Reject all subscription requests
manual: manually process subscription requests
&NBSP
Create groups: Rostergroup group = Roster.creategroup ("university");
Add the Rosterentry object to the group: Group.addentry (Entry);
7, Rosterentry
represents each record in the roster (roster). It contains the user's Jid, user name, or user-assigned nickname.
8, Rostergroup The
represents a rosterentry group. Can be added using AddEntry (Rosterentry entry). Contains (String user) determines whether a user is in a group. Of course RemoveEntry (Rosterentry entry) is removed from the group. GetEntries ()
Get all rosterentry.
9, Presence
Represents the packet of a XMPP state. Each presence packet has a state. is represented by the value of the enumeration type Presence.type:
Available--(default) User idle state
Unavailable--users don't have time to read the news
Subscribe--Request to subscribe to others, that is, request to add each other as friends
Subscribed--Unified by others to subscribe, that is, confirmed by the other side as a friend
Unsubscribe--He cancels a subscription, asks to delete a friend
Unsubscribed--refusing to be subscribed, that is, to reject the add request
Error--Current state packet there are errors
Inline two enumeration types: Presence.mode and Presence.type.
You can use SetStatus to customize the current state of the user (like QQ)
multiuserchat Chat Room
Import Java.io.BufferedReader;
Import Java.io.InputStreamReader;
Import java.util.ArrayList;
Import java.util.Collection;
Import Java.util.Iterator;
Import java.util.List;
Import Org.jivesoftware.smack.Chat;
Import org.jivesoftware.smack.ConnectionConfiguration;
Import Org.jivesoftware.smack.MessageListener;
Import Org.jivesoftware.smack.PacketListener;
Import org.jivesoftware.smack.SmackConfiguration;
Import org.jivesoftware.smack.XMPPConnection;
Import org.jivesoftware.smack.XMPPException;
Import Org.jivesoftware.smack.packet.Message;
Import Org.jivesoftware.smack.packet.Packet;
Import Org.jivesoftware.smack.provider.ProviderManager;
Import Org.jivesoftware.smackx.Form;
Import Org.jivesoftware.smackx.FormField;
Import Org.jivesoftware.smackx.ServiceDiscoveryManager;
Import Org.jivesoftware.smackx.muc.DefaultParticipantStatusListener;
Import Org.jivesoftware.smackx.muc.DefaultUserStatusListener; Import Org.jivesoftware.smackx.muc.DiscussionHistory;
Import Org.jivesoftware.smackx.muc.HostedRoom;
Import Org.jivesoftware.smackx.muc.InvitationListener;
Import Org.jivesoftware.smackx.muc.InvitationRejectionListener;
Import Org.jivesoftware.smackx.muc.MultiUserChat;
Import Org.jivesoftware.smackx.muc.RoomInfo;
Import Org.jivesoftware.smackx.muc.SubjectUpdatedListener;
Import org.jivesoftware.smackx.packet.ChatStateExtension;
Import Org.jivesoftware.smackx.packet.DiscoverInfo;
Import Org.jivesoftware.smackx.packet.DiscoverItems;
Import Org.jivesoftware.smackx.packet.OfflineMessageInfo;
Import Org.jivesoftware.smackx.packet.OfflineMessageRequest;
Import Org.jivesoftware.smackx.provider.AdHocCommandDataProvider;
Import Org.jivesoftware.smackx.provider.BytestreamsProvider;
Import Org.jivesoftware.smackx.provider.DataFormProvider;
Import Org.jivesoftware.smackx.provider.DiscoverInfoProvider;
Import Org.jivesoftware.smackx.provider.DiscoverItemsProvider; Import Org.jivesoftware.smackx.provider.IBBPrOviders;
Import Org.jivesoftware.smackx.provider.MUCAdminProvider;
Import Org.jivesoftware.smackx.provider.MUCOwnerProvider;
Import Org.jivesoftware.smackx.provider.MUCUserProvider;
Import Org.jivesoftware.smackx.provider.StreamInitiationProvider;
Import Org.jivesoftware.smackx.provider.VCardProvider;
Import Org.jivesoftware.smackx.provider.XHTMLExtensionProvider;
public class TestSmack2 {public static void main (string[] args) {xmppconnection.debug_enabled = true;
Final Connectionconfiguration connectionconfig = new Connectionconfiguration ("PC2010102716", 5222, "");
Connectionconfig.setsaslauthenticationenabled (FALSE);
Providermanager pm = providermanager.getinstance ();
Configure (PM);
try {xmppconnection connection = new Xmppconnection (connectionconfig);
Connection.connect ();//Connect initfeatures (connection); Connection.login ("Test", "test")//Login//chat room//multiuserchat multiuserchat = new multIuserchat (Connection, new Invitationlistener () {});
Find Service System.out.println (Connection.getservicename ());
list<string> col = getconferenceservices (Connection.getservicename (), connection);
for (Object acol:col) {String service = (string) Acol;
Chat rooms on the query server collection<hostedroom> rooms = multiuserchat.gethostedrooms (connection, service); for (Hostedroom room:rooms) {//view Room message System.out.println (room.getname () + "-" +room.getjid ()
);
Roominfo Roominfo = Multiuserchat.getroominfo (connection, Room.getjid ());
if (roominfo!= null) {System.out.println (Roominfo.getoccupantscount () + ":" + roominfo.getsubject ()); }}/*---Create a chat room with a default configuration---First look at the official documentation: creates a new multi user cha T with the specified connection and room name. Note:no * information is sent to or received fromThe server until your attempt to * {@link #join (String) join} The chat room. On some server implementations, * The room is not being created until the first person joins it * The most important sentence : The chat room will not be created until the user invokes the Join method * * Multiuserchat MUC = new Multiuserchat (connection, "instant@conference.pc2010
102716 ");
Muc.create ("user1");
Muc.sendconfigurationform (New Form (Form.type_submit));
----Create a manual configuration chat room----MUC = new Multiuserchat (connection, "reserved4@conference.pc2010102716");
Destroy chat room//muc.destroy ("Test", null);
Muc.create ("User2");
Get the chat room configuration Form form = Muc.getconfigurationform ();
Create a new form to submit based on the original form submitform = Form.createanswerform (); Add a default reply to the submitted form for (iterator<formfield> fields = Form.getfields (); Fields.hasnext ();)
{FormField field = (FormField) fields.next (); if (! FormField.TYPE_HIDDEN.equals (Field.getType ()) && field.getvariable ()!= null) {Submitform.setdefaultanswer () (field.getvariable ());
}//Reset the chat room name Submitform.setanswer ("Muc#roomconfig_roomname", "Reserved4 Room");
Set up the new owner of the chat room, list<string> owners = newer arraylist<string> ();
Owners.add ("test@pc2010102716");
Submitform.setanswer ("Muc#roomconfig_roomowners", owners);
Set Password Submitform.setanswer ("Muc#roomconfig_passwordprotectedroom", true);
Submitform.setanswer ("Muc#roomconfig_roomsecret", "reserved");
Set Description Submitform.setanswer ("Muc#roomconfig_roomdesc", "newly created reserved chat room");
Setting up a chat room is a persistent chat room that will be saved//submitform.setanswer ("Muc#roomconfig_persistentroom", true);
Send completed form to server configuration chat room muc.sendconfigurationform (submitform);
Join the chat room (using the nickname drunk Caterpillar, using the password ddd) Muc = new Multiuserchat (connection, "ddd@conference.pc2010102716"); Muc.join ("The Drunken Caterpillar"),"DDD"); Listener Message Muc.addmessagelistener (new Packetlistener () {@Override public void Processpacket (Packe
T packet) {Message message = (message) packet;
System.out.println (Message.getfrom () + ":" + message.getbody ());;}};
MUC = new Multiuserchat (connection, "ddd@conference.pc2010102716");
Muc.join ("Drunken Caterpillar", "ddd"); Join the chat room (use nickname drunk caterpillar, use password DDD) and get the last 5 messages in the chat room/Note: The Addmessagelistener listener must not be able to monitor the required 5 messages before this join method MUC = new
Multiuserchat (Connection, "ddd@conference.pc2010102716");
Discussionhistory history = new Discussionhistory ();
History.setmaxstanzas (5);
Muc.join ("Drunken Caterpillar", "ddd", History, Smackconfiguration.getpacketreplytimeout ());
Listen for users who refuse to join the chat room Muc.addinvitationrejectionlistener (new Invitationrejectionlistener () {@Override public void invitationdeclined (string invitee, String REason) {System.out.println (invitee + "reject invitation, reason is" + reason);
}
});
Invite users to join the chat room muc.invite ("test3@pc2010102716", "everyone to talk about life");
Listen to the invitation to join the chat room request Multiuserchat.addinvitationlistener (connection, new Invitationlistener () {@Override public void invitationreceived (Xmppconnection conn, string Room, string inviter, String reason, string password, Mess Age Message {//example: direct refusal to invite Multiuserchat.decline (conn, room, Inviter, "You are busy!"
");
}
});
Get chat room information according to Roomjid roominfo roominfo = Multiuserchat.getroominfo (Connection, "ddd@conference.pc2010102716");
System.out.println (Roominfo.getroom () + "-" + roominfo.getsubject () + "-" + Roominfo.getoccupantscount ()); Determine whether the user supports Multi-User Chat protocol//NOTE: Need to add a resource identifier Boolean supports = Multiuserchat.isserviceenabled (connection,
"Test3@pc2010102716/spark"); Get a chat that a user has joinedRoom if (supports) {iterator<string> joinedrooms = multiuserchat.getjoinedrooms (Connection, "test3@pc
2010102716/spark ");
while (Joinedrooms.hasnext ()) {System.out.println ("Test3 has joined Room" + Joinedrooms.next ()); }//private chat with chat room Chat Chat = muc.createprivatechat ("ddd@conference.pc2010102716/Bird", New Messa Gelistener () {@Override public void ProcessMessage (Chat Chat, message message) {System
. OUT.PRINTLN ("Private chat:received message from" + message.getfrom () + "-" + message.getbody ());
}
}); Chat.sendmessage ("You don't have to work overtime today?")
"); Change the chat room theme Muc.addsubjectupdatedlistener (new Subjectupdatedlistener () {@Override public void s Ubjectupdated (string subject, string from) {System.out.println (' subject updated to ' + subject + ' by ' + from
);
}
}); Muc.changesubject ("New subjeCt11 "); /* A member may have four roles: 1: Moderator (Moderator) (the most privileged role, managing the role of other members in the chat Room 2: Participants (Participant 3: Visitors (Visitor) (Cannot send messages to all members) 4: None (no role) (none)////* Chat room user can have 5 kinds of dependencies * 1, owners owner * 2, Admin admin * 3, Members member * 4, expelled by Outcast * 5, none (no dependencies) none//configure chat room for moderated chat room form
= Muc.getconfigurationform ();
Form answerform = Form.createanswerform ();
Answerform.setanswer ("Muc#roomconfig_moderatedroom", "1");
Muc.sendconfigurationform (Answerform); Monitor your own state changes and events Muc.adduserstatuslistener (new Defaultuserstatuslistener () {@Override public vo
ID voicerevoked () {super.voicerevoked ();
System.out.println ("You are forbidden!");
@Override public void voicegranted () {super.voicegranted ();
SYSTEM.OUT.PRINTLN ("You have been approved to speak!");
} @Override public void membershipgranted () {super.membershipgranted ();
System.out.println ("You are given a member privilege");
@Override public void membershiprevoked () {super.membershiprevoked ();
System.out.println ("You are relieved of the member authority");
@Override public void admingranted () {super.admingranted ();
System.out.println ("You are given Administrator privileges");
@Override public void adminrevoked () {super.adminrevoked ();
SYSTEM.OUT.PRINTLN ("You have been relieved of administrator privileges");
}
//......
});
Owner (owner) approved test3 say Muc.grantvoice ("test3@pc2010102716");
Listen for other people's status change Muc.addparticipantstatuslistener (new Defaultparticipantstatuslistener () {@Override
public void voicegranted (String participant) {super.voicegranted (participant); System.oUT.PRINTLN (participant + "was approved to speak!"); @Override public void voicerevoked (String participant) {super.voicerevoked (part
Icipant);
SYSTEM.OUT.PRINTLN (participant + "forbidden!"); @Override public void membershiprevoked (String participant) {Super.membershipre
voked (participant); @Override public void admingranted (String participant) {super.admingranted (part
Icipant); @Override public void adminrevoked (String participant) {super.adminrevoked (part
Icipant);
}
});
Owner (owner) approves TEST3 Administrator privileges Muc.grantadmin ("test3@pc2010102716");
Send Message BufferedReader Cmdin = new BufferedReader (new InputStreamReader (system.in));
while (true) {try {String cmd = Cmdin.readline (); if ("!q". EqualSignorecase (cmd)) {break;
}}catch (Exception ex) {}} connection.disconnect ();
System.exit (0);
catch (Exception e) {e.printstacktrace (); } public static list<string> getconferenceservices (String server, xmppconnection connection) throws Exce
ption {list<string> answer = new arraylist<string> ();
Servicediscoverymanager Discomanager = servicediscoverymanager.getinstancefor (connection);
Discoveritems items = discomanager.discoveritems (server); for (iterator<discoveritems.item> it = Items.getitems (); It.hasnext ();)
{Discoveritems.item Item = (discoveritems.item) it.next (); if (Item.getentityid (). StartsWith ("conference") | | Item.getentityid (). StartsWith ("private") {Answer.add (item
. Getentityid ()); else {try {discoverinfo info = Discomanager.discoVerinfo (Item.getentityid ());
if (Info.containsfeature ("Http://jabber.org/protocol/muc")) {Answer.add (Item.getentityid ());
The catch (Xmppexception e) {}} is return answer; } private static void Configure (Providermanager pm) {//Service Discovery # Items Pm.addiqprovider ("
Query "," Http://jabber.org/protocol/disco#items ", New Discoveritemsprovider ()); Service Discovery # Info Pm.addiqprovider ("Query", "Http://jabber.org/protocol/disco#info", New Discoverinfoprovi
Der ()); Service Discovery # Items Pm.addiqprovider ("Query", "Http://jabber.org/protocol/disco#items", New DISCOVERITEMSPR
Ovider ()); Service Discovery # Info Pm.addiqprovider ("Query", "Http://jabber.org/protocol/disco#info", New Discoverinfoprovi
Der ()); Offline message Requests pm.addiqprovider ("Offline", "Http://jabber.org/protoCol/offline ", New Offlinemessagerequest.provider ()); Offline Message indicator Pm.addextensionprovider ("Offline", "Http://jabber.org/protocol/offline", New Offlinem
Essageinfo.provider ());
vcard Pm.addiqprovider ("vcard", "vcard-temp", New Vcardprovider ());
Filetransfer pm.addiqprovider ("Si", "http://jabber.org/protocol/si", New Streaminitiationprovider ());
Pm.addiqprovider ("Query", "Http://jabber.org/protocol/bytestreams", New Bytestreamsprovider ());
Pm.addiqprovider ("Open", "Http://jabber.org/protocol/ibb", New Ibbproviders.open ());
Pm.addiqprovider ("Close", "Http://jabber.org/protocol/ibb", New Ibbproviders.close ());
Pm.addextensionprovider ("Data", "Http://jabber.org/protocol/ibb", New Ibbproviders.data ());
Data Forms Pm.addextensionprovider ("x", "Jabber:x:data", New Dataformprovider ()); HTML Pm.addextensionprovider ("HTML", "http://jabber.org/protocol/Xhtml-im ", New Xhtmlextensionprovider ()); Ad-hoc command Pm.addiqprovider ("command", "Http://jabber.org/protocol/commands", New Adhoccommanddataprovider ()
);
Chat State Chatstateextension.provider chatstate = new Chatstateextension.provider ();
Pm.addextensionprovider ("Active", "http://jabber.org/protocol/chatstates", chatstate);
Pm.addextensionprovider ("Composing", "Http://jabber.org/protocol/chatstates", chatstate);
Pm.addextensionprovider ("Paused", "http://jabber.org/protocol/chatstates", chatstate);
Pm.addextensionprovider ("Inactive", "http://jabber.org/protocol/chatstates", chatstate);
Pm.addextensionprovider ("Gone", "http://jabber.org/protocol/chatstates", chatstate);
MUC User,admin,owner Pm.addextensionprovider ("x", "Http://jabber.org/protocol/muc#user", New Mucuserprovider ());
Pm.addiqprovider ("Query", "Http://jabber.org/protocol/muc#admin", New Mucadminprovider ()); Pm.addiqprovider ("QuerY "," Http://jabber.org/protocol/muc#owner ", New Mucownerprovider ()); } private static void Initfeatures (Xmppconnection xmppconnection) {servicediscoverymanager.setidentityname ("A
Ndroid_im ");
Servicediscoverymanager.setidentitytype ("Phone");
Servicediscoverymanager SDM = servicediscoverymanager.getinstancefor (xmppconnection);
if (SDM = = null) {SDM = new Servicediscoverymanager (xmppconnection);
} sdm.addfeature ("Http://jabber.org/protocol/disco#info");
Sdm.addfeature ("Http://jabber.org/protocol/caps");
Sdm.addfeature ("Urn:xmpp:avatar:metadata");
Sdm.addfeature ("urn:xmpp:avatar:metadata+notify");
Sdm.addfeature ("Urn:xmpp:avatar:data");
Sdm.addfeature ("Http://jabber.org/protocol/nick");
Sdm.addfeature ("http://jabber.org/protocol/nick+notify");
Sdm.addfeature ("Http://jabber.org/protocol/xhtml-im");
Sdm.addfeature ("Http://jabber.org/protocol/muc"); Sdm.addfeature ("Http://jabber.org/protoCol/commands ");
Sdm.addfeature ("Http://jabber.org/protocol/si/profile/file-transfer");
Sdm.addfeature ("Http://jabber.org/protocol/si");
Sdm.addfeature ("Http://jabber.org/protocol/bytestreams");
Sdm.addfeature ("Http://jabber.org/protocol/ibb");
Sdm.addfeature ("Http://jabber.org/protocol/feature-neg");
Sdm.addfeature ("Jabber:iq:privacy");
}
}
There are two spark in the chat room list for the client. A different reason: the values of occupantscount and subject cannot be obtained when using the following code:
System.out.println (Roominfo.getoccupantscount () + ":" + roominfo.getsubject ());
This is due to a bug on the OpenFire side (for the moment, I don't know why openfire do this). First modify a bug in smack and modify the Roominfo (Discoverinfo Info) method of the Roominfo class:
iterator<string> values = Form.getfield ("Muc#roominfo_subject"). GetValues ();
if (Values.hasnext ()) {
this.subject = Values.next ();
}
else {
this.subject = "";
}
To
Final FormField Subjfield = Form.getfield ("Muc#roominfo_subject");
This.subject = Subjfield = = null? "": Subjfield.getvalues (). Next ();
Modify OpenFire's source code, Org/jivesoftware/openfire/muc/spi/multiuserchatserviceimpl class's public dataform Getextendedinfo (String Name, String node, JID Senderjid) method:
/*final FormField FIELDOCC = Dataform.addfield (); * *
fieldsubj.setvariable ("muc#roominfo_occupants");
Fieldsubj.setlabel (localeutils.getlocalizedstring ("muc.extended.info.occupants"));
Fieldsubj.addvalue (Integer.tostring (Room.getoccupantscount ()));
To
Final FormField fieldoccu= Dataform.addfield ();
Fieldoccu.setvariable ("muc#roominfo_occupants");
Fieldoccu.setlabel (localeutils.getlocalizedstring ("muc.extended.info.occupants"));
Fieldoccu.addvalue (Integer.tostring (Room.getoccupantscount ()));
Using asmack to develop an IM system based on Android.