因为asmack在/META-INF缺少一个smack.providers 文件,所以需要在建立connection之前手动添加Provider,不然会出现 空指针异常或者是ClassCastExceptions
至于asmack为什么不能自动addExtensionProvider,我也不清楚,请明白人留言告知。
这个问题的详细讨论:http://stackoverflow.com/questions/5910219/problem-using-usersearch-in-xmpp-with-asmack
手动加入providers的函数
public void configure(ProviderManager pm) {
// Private Data Storage
pm.addIQProvider("query","jabber:iq:private", new PrivateDataManager.PrivateDataIQProvider());
// Time
try {
pm.addIQProvider("query","jabber:iq:time", Class.forName("org.jivesoftware.smackx.packet.Time"));
} catch (ClassNotFoundException e) {
Log.w("TestClient", "Can't load class for org.jivesoftware.smackx.packet.Time");
}
// Roster Exchange
pm.addExtensionProvider("x","jabber:x:roster", new RosterExchangeProvider());
// Message Events
pm.addExtensionProvider("x","jabber:x:event", new MessageEventProvider());
// Chat State
pm.addExtensionProvider("active","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
pm.addExtensionProvider("composing","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
pm.addExtensionProvider("paused","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
pm.addExtensionProvider("inactive","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
pm.addExtensionProvider("gone","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
// XHTML
pm.addExtensionProvider("html","http://jabber.org/protocol/xhtml-im", new XHTMLExtensionProvider());
// Group Chat Invitations
pm.addExtensionProvider("x","jabber:x:conference", new GroupChatInvitation.Provider());
// 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 DiscoverInfoProvider());
// Data Forms
pm.addExtensionProvider("x","jabber:x:data", new DataFormProvider());
// MUC User
pm.addExtensionProvider("x","http://jabber.org/protocol/muc#user", new MUCUserProvider());
// MUC Admin
pm.addIQProvider("query","http://jabber.org/protocol/muc#admin", new MUCAdminProvider());
// MUC Owner
pm.addIQProvider("query","http://jabber.org/protocol/muc#owner", new MUCOwnerProvider());
// Delayed Delivery
pm.addExtensionProvider("x","jabber:x:delay", new DelayInformationProvider());
// Version
try {
pm.addIQProvider("query","jabber:iq:version", Class.forName("org.jivesoftware.smackx.packet.Version"));
} catch (ClassNotFoundException e) {
// Not sure what's happening here.
}
// VCard
pm.addIQProvider("vCard","vcard-temp", new VCardProvider());
// 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 OfflineMessageInfo.Provider());
// Last Activity
pm.addIQProvider("query","jabber:iq:last", new LastActivity.Provider());
// User Search
pm.addIQProvider("query","jabber:iq:search", new UserSearch.Provider());
// SharedGroupsInfo
pm.addIQProvider("sharedgroup","http://www.jivesoftware.org/protocol/sharedgroup", new SharedGroupsInfo.Provider());
// JEP-33: Extended Stanza Addressing
pm.addExtensionProvider("addresses","http://jabber.org/protocol/address", new MultipleAddressesProvider());
// FileTransfer
pm.addIQProvider("si","http://jabber.org/protocol/si", new StreamInitiationProvider());
pm.addIQProvider("query","http://jabber.org/protocol/bytestreams", new BytestreamsProvider());
// Privacy
pm.addIQProvider("query","jabber:iq:privacy", new PrivacyProvider());
pm.addIQProvider("command", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider());
pm.addExtensionProvider("malformed-action", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.MalformedActionError());
pm.addExtensionProvider("bad-locale", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.BadLocaleError());
pm.addExtensionProvider("bad-payload", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.BadPayloadError());
pm.addExtensionProvider("bad-sessionid", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.BadSessionIDError());
pm.addExtensionProvider("session-expired", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.SessionExpiredError());}
在创建Connection之前执行
configure(ProviderManager.getInstance());
搜索好友的实现:
Form.getSearchForm()这个方法要求的参数是一个服务名,openfire默认的搜索服务是search.+域名。
Form.setAnswer();这个方法意思是,把某个字段设成true就会在那个字段里搜索关键字,search字段设置要搜索的关键字,什么不输入不会返回。
try{
UserSearchManager search = new UserSearchManager(conn);
Form searchForm = search.getSearchForm("search.202.118.239.46");
Form answerForm = searchForm.createAnswerForm();
answerForm.setAnswer("Username", true);
answerForm.setAnswer("search", UserName.getText().toString());
ReportedData data = search.getSearchResults(answerForm,"search.202.118.239.46");
Iterator<Row> it = data.getRows();
Row row=null;
String ansS="";
while(it.hasNext()){
row=it.next();
ansS+=row.getValues("Username").next().toString()+"\n";
//Log.i("Username",row.getValues("Username").next().toString());
}
Toast.makeText(this,ansS, Toast.LENGTH_SHORT).show();
}catch(Exception e){
Toast.makeText(this,e.getMessage()+" "+e.getClass().toString(), Toast.LENGTH_SHORT).show();
}
添加好友的实现: Roster roster = conn.getRoster();roster.createEntry(UserName.getText().toString(), null, new String[] { "friends" });Toast.makeText(this, "success", Toast.LENGTH_SHORT).show();列出所有好友的实现:
roster=conn.getRoster();
Collection<RosterEntry> it = roster.getEntries();
friends = new ArrayList<String>();
for(RosterEntry rosterEnter:it){
friends.add(rosterEnter.getUser());
}
if (friends.size()==0){
friends.add("You have no friend");