当在 XMPP 中使用 UserSearch 和 aSmack 时,getSearchForm 返回 null

发布于 2024-11-05 07:47:48 字数 666 浏览 1 评论 0原文

我有这段代码,几乎没有对示例进行修改:

                UserSearchManager usm = new UserSearchManager(conn);
                Form searchForm = usm.getSearchForm("search.myserver.com");
                Form answerForm = searchForm.createAnswerForm();
                answerForm.setAnswer("Username", true);
                answerForm.setAnswer("search", contact.getJid());
                ReportedData data = usm.getSearchResults(answerForm, "search.myserver.com");

这在桌面环境中使用 Smack 库完美运行,但我无法让它在 Android 中运行(我必须使用 asmack)。

问题是 searchForm 为 null,因为 getSearchForm 返回 null。这似乎很奇怪,因为我似乎找不到任何关于该方法应返回 null 的情况的文档。

服务器是Openfire,如果有帮助的话。

I have this code, almost unmodified from examples:

                UserSearchManager usm = new UserSearchManager(conn);
                Form searchForm = usm.getSearchForm("search.myserver.com");
                Form answerForm = searchForm.createAnswerForm();
                answerForm.setAnswer("Username", true);
                answerForm.setAnswer("search", contact.getJid());
                ReportedData data = usm.getSearchResults(answerForm, "search.myserver.com");

This works perfectly in a Desktop environment, using Smack library, but I can't get it to work in Android (where I have to use asmack).

The problem is searchForm is null because getSearchForm returns null. This seems to be pretty odd as I can't seem to find any documentation on which cases that method should return null.

The server is Openfire, if it helps.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

自由如风 2024-11-12 07:47:48

更新 04/2014

下面的原始答案包含现在旧的和过时的信息。从 aSmack 0.8 开始,不再需要手动配置提供程序管理器。按照 aSmack 自述文件的指示调用 SmackAndroid.init(Context) 来处理所有必要的初始化。

原始答案

最后,这个问题对所有人来说都是全球性的。这似乎是一个已知问题:smack.providers 文件(通常位于普通版本 smack 中的 /META-INF 文件夹中)由于其 jar 打包而无法在 Android 中加载。因此,所有提供程序都必须手动初始化,如 Mike Ryan 在该线程中的回答所示:http://community.igniterealtime。 org/message/201866#201866

我删除了对我不起作用的东西,这就是结果。

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());

我只评论了几行,瞧 这应该在实例化 XMPPConnection 之前调用,并使用如下一行:

    configure(ProviderManager.getInstance());

现在我必须处理其他问题,但至少这个问题已经解决了:)

Update 04/2014

The original answer below contains now old and outdated information. Since aSmack 0.8 it's no longer necessary to manually configure the provider manager. Calling SmackAndroid.init(Context) as the aSmack README tells you to do, takes care of all necessary initializations.

Original Answer

In the end, the problem was global to all asmack. It seems it's a known issue: the smack.providers file, usually in /META-INF folder in normal versions of smack, can't be loaded in Android because its jar packaging. So all the providers must be initialized by hand, as shown in Mike Ryan's answer in this thread: http://community.igniterealtime.org/message/201866#201866

I removed the stuff that didn't worked for me, and this is the result.

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());

}

I only commented a couple lines, and voilà. This should be called before instantiating XMPPConnection, with a line like this:

    configure(ProviderManager.getInstance());

Now I'll have to deal with my other problems, but at least this one is solved :)

祁梦 2024-11-12 07:47:48

在代码示例 XmppTool.java 中, getSearchFrom 用于 searchUsers() 中。

public List<User> searchUsers(String serverDomain,String userName){
        List<User> list = new ArrayList<User>();
        UserSearchManager userSearchManager = new UserSearchManager(con);
        try {
            Form searchForm = userSearchManager.getSearchForm("search."+serverDomain);
            Form answerForm = searchForm.createAnswerForm();
            answerForm.setAnswer("Username", true);
            answerForm.setAnswer("Name", true);
            answerForm.setAnswer("search", userName);
            ReportedData data = userSearchManager.getSearchResults(answerForm, "search."+serverDomain);
            Iterator<Row> rows = data.getRows();
            while(rows.hasNext()){
                User user = new User();
                Row row = rows.next();
                user.setUserName(row.getValues("Username").next().toString());
                user.setName(row.getValues("Name").next().toString());
                SLog.i(tag, user.toString());
                list.add(user);
            }
        } catch (XMPPException e) {
            SLog.e(tag, Log.getStackTraceString(e));
        }
        return list;
    }

您可以参考java文件中的全局设置来修复您的代码。

In the code example XmppTool.java, getSearchFrom is used in searchUsers().

public List<User> searchUsers(String serverDomain,String userName){
        List<User> list = new ArrayList<User>();
        UserSearchManager userSearchManager = new UserSearchManager(con);
        try {
            Form searchForm = userSearchManager.getSearchForm("search."+serverDomain);
            Form answerForm = searchForm.createAnswerForm();
            answerForm.setAnswer("Username", true);
            answerForm.setAnswer("Name", true);
            answerForm.setAnswer("search", userName);
            ReportedData data = userSearchManager.getSearchResults(answerForm, "search."+serverDomain);
            Iterator<Row> rows = data.getRows();
            while(rows.hasNext()){
                User user = new User();
                Row row = rows.next();
                user.setUserName(row.getValues("Username").next().toString());
                user.setName(row.getValues("Name").next().toString());
                SLog.i(tag, user.toString());
                list.add(user);
            }
        } catch (XMPPException e) {
            SLog.e(tag, Log.getStackTraceString(e));
        }
        return list;
    }

You may refer to the global settings in the java file to repair your code.

ヤ经典坏疍 2024-11-12 07:47:48

UserSearchManager的Javadoc解释如下:

UserSearchManager 是一个基于 Jabber 搜索服务 (JEP-055) 构建的外观,允许搜索 Jabber 服务器上的存储库。此实现允许搜索实现的透明度(DataForms 或无 DataForms),但允许用户简单地使用 DataForm 模型来支持这两种类型。

 XMPPConnection con = new XMPPConnection("jabber.org");
 con.login("john", "doe");
 UserSearchManager search = new UserSearchManager(con, "users.jabber.org");
 Form searchForm = search.getSearchForm();
 Form answerForm = searchForm.createAnswerForm();
 answerForm.setAnswer("last", "DeMoro");
 ReportedData data = search.getSearchResults(answerForm);
 // Use Returned Data

The Javadoc of UserSearchManager explains as follows:

The UserSearchManager is a facade built upon Jabber Search Services (JEP-055) to allow for searching repositories on a Jabber Server. This implementation allows for transparency of implementation of searching (DataForms or No DataForms), but allows the user to simply use the DataForm model for both types of support.

 XMPPConnection con = new XMPPConnection("jabber.org");
 con.login("john", "doe");
 UserSearchManager search = new UserSearchManager(con, "users.jabber.org");
 Form searchForm = search.getSearchForm();
 Form answerForm = searchForm.createAnswerForm();
 answerForm.setAnswer("last", "DeMoro");
 ReportedData data = search.getSearchResults(answerForm);
 // Use Returned Data
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文