Search code examples
javaandroidxmppsmackasmack

getSearchForm returns null when using UserSearch in XMPP with aSmack


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.


Solution

  • 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 :)