因为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=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");