在 Android 中使用 xmpp/UserSearchManager 搜索现有用户

Posted

技术标签:

【中文标题】在 Android 中使用 xmpp/UserSearchManager 搜索现有用户【英文标题】:Search for existing user using xmpp/UserSearchManager in Android 【发布时间】:2011-11-21 15:00:16 【问题描述】:

我已经经历了this1、this2和this3,但仍然找不到问题的解决方案。

我可以知道我在这段代码中的问题出在哪里:

    从文本框中获取输入并 传递该值以检查文本框中提供的用户名是否存在 每当我单击检查按钮时,仅显示“调用的函数”并且不执行搜索。

这是我到目前为止所做的代码。

public class Registration extends Activity implements OnClickListener 
    private final static String SERVER_HOST = "10.0.2.2";
    private final static int SERVER_PORT = 5222;
    private static final String TAG = null;
    private ProviderManager pm;
    private EditText username;
    private Button btn;

    private XMPPConnection connection;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.registration);

        try 

            initConnection();
         catch (XMPPException e) 
            e.printStackTrace();
        

        username = (EditText) this.findViewById(R.id.txtregusername);

        btn=(Button) this.findViewById(R.id.btncheck);
        btn.setOnClickListener(this);      


    @Override
    public void onClick(View v) 
        switch(v.getId())
        
        case R.id.btncheck:
            try 
                check();
             catch (XMPPException e) 
                // TODO Auto-generated catch block
                e.printStackTrace();
            

        break;

        

    

    private void check() throws XMPPException 
         Toast.makeText(this,"Function called",Toast.LENGTH_SHORT).show();

        pm.addIQProvider("query","jabber:iq:search", new UserSearch.Provider());
        UserSearchManager search = new UserSearchManager(connection);  

        Form searchForm = search.getSearchForm("search."+connection.getServiceName());  
        Form answerForm = searchForm.createAnswerForm();  
        answerForm.setAnswer("Username", true);  
        Toast.makeText(this,username.getText().toString(),Toast.LENGTH_SHORT).show();
        answerForm.setAnswer("search", username.getText().toString());  
        ReportedData data = search.getSearchResults(answerForm,"search."+connection.getServiceName());  

    if(data.getRows() != null)
        
             Toast.makeText(this,"Username Exists",Toast.LENGTH_SHORT).show();
        
        else
        
             Toast.makeText(this,"Username Available",Toast.LENGTH_SHORT).show();

        

    


    private void initConnection() throws XMPPException
     ConnectionConfiguration config=new ConnectionConfiguration(SERVER_HOST,SERVER_PORT);
      config.setSecurityMode(SecurityMode.enabled);
      config.setSASLAuthenticationEnabled(true);
      connection=new XMPPConnection(config);

      try     

       connection.connect();
       

    catch (XMPPException e)      
          Log.e(TAG, "Error connection to XMPP Server");     
          e.printStackTrace(); 
           


       


【问题讨论】:

这是什么问题?! :) 你能发布异常日志,或者描述问题吗? 正如我在 3 中也提到的,问题是没有执行搜索我不知道问题出在哪里。自从 5 小时以来我一直在尝试这个以找到错误。 如果用户已经存在,你为什么不只是依赖 createUser(无论被调用的)函数会抛出异常,而不是你捕获异常。为什么需要显式检查用户是否已经存在? @hovanessyan: 我很欣赏你的建议..但如果我错了我很抱歉我已经尝试过这个 try AccountManager manager = conn.getAccountManager(); manager.createAccount(usename,password); catch(...) 但可以得到任何结果所以..你能显示这个细节吗 您是否检查过是否建立了与服务器的连接?您可以向服务器查询某些内容并返回结果吗?也许您可以尝试使用现有用户登录并断开与服务器的连接,并监控 xmpp 的日志(是否是 Openfire)以查看通信是否正常? 【参考方案1】:

试试这个。它解决了我的问题。

UserSearchManager search = new UserSearchManager(mXMPPConnection);  

Form searchForm = search.getSearchForm("search."+mXMPPConnection.getServiceName());

Form answerForm = searchForm.createAnswerForm();  
answerForm.setAnswer("Username", true);  

answerForm.setAnswer("search", user);  

org.jivesoftware.smackx.ReportedData data = search.getSearchResults(answerForm,"search."+mXMPPConnection.getServiceName());  

if(data.getRows() != null)

    Iterator<Row> it = data.getRows();
    while(it.hasNext())
    
        Row row = it.next();
        Iterator iterator = row.getValues("jid");
        if(iterator.hasNext())
        
            String value = iterator.next().toString();
            Log.i("Iteartor values......"," "+value);
        
        //Log.i("Iteartor values......"," "+value);
    
    Toast.makeText(_service,"Username Exists",Toast.LENGTH_SHORT).show();
    );

如果 Server 没有任何具有该指定名称的条目,则 Itearator 它没有值,并且代码不会进入 while(it.hasNext)。

【讨论】:

IllegalArgumentException 在 Form.set Answer("Username",true);有什么理由吗?是不是服务器上缺少某些权限? 在表单中获取空指针 searchForm = search.getSearchForm("search."+mXMPPConnection.getServiceName()); @SagarNayak 可能是您的 mXMPPConnection 为空。【参考方案2】:

您好,您需要先使用 ProviderManager,否则搜索将无法正常工作。以下是我的工作代码,完美运行,希望对您有所帮助:

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.PrivacyList;
import org.jivesoftware.smack.PrivacyListManager;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.PrivacyItem;
import org.jivesoftware.smack.provider.PrivacyProvider;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smackx.Form;
import org.jivesoftware.smackx.GroupChatInvitation;
import org.jivesoftware.smackx.PrivateDataManager;
import org.jivesoftware.smackx.ReportedData.Row;
import org.jivesoftware.smackx.bytestreams.socks5.provider.BytestreamsProvider;
import org.jivesoftware.smackx.packet.ChatStateExtension;
import org.jivesoftware.smackx.packet.LastActivity;
import org.jivesoftware.smackx.packet.OfflineMessageInfo;
import org.jivesoftware.smackx.packet.OfflineMessageRequest;
import org.jivesoftware.smackx.packet.SharedGroupsInfo;
import org.jivesoftware.smackx.packet.VCard;
import org.jivesoftware.smackx.provider.AdHocCommandDataProvider;
import org.jivesoftware.smackx.provider.DataFormProvider;
import org.jivesoftware.smackx.provider.DelayInformationProvider;
import org.jivesoftware.smackx.provider.DiscoverInfoProvider;
import org.jivesoftware.smackx.provider.DiscoverItemsProvider;
import org.jivesoftware.smackx.provider.MUCAdminProvider;
import org.jivesoftware.smackx.provider.MUCOwnerProvider;
import org.jivesoftware.smackx.provider.MUCUserProvider;
import org.jivesoftware.smackx.provider.MessageEventProvider;
import org.jivesoftware.smackx.provider.MultipleAddressesProvider;
import org.jivesoftware.smackx.provider.RosterExchangeProvider;
import org.jivesoftware.smackx.provider.StreamInitiationProvider;
import org.jivesoftware.smackx.provider.VCardProvider;
import org.jivesoftware.smackx.provider.XhtmlExtensionProvider;
import org.jivesoftware.smackx.search.UserSearch;
import org.jivesoftware.smackx.search.UserSearchManager;
    public static List<String> getUserListBySearch(XMPPConnection mXMPPConnection, String searchString)
            ProviderManager.getInstance().addIQProvider("query","jabber:iq:search", new UserSearch.Provider());
            List<String> l = new ArrayList<String>();
            try 
                UserSearchManager search = new UserSearchManager(mXMPPConnection);  

                Form searchForm = search.getSearchForm("search."+mXMPPConnection.getServiceName());
                Form answerForm = searchForm.createAnswerForm();  
                answerForm.setAnswer("Username", true);  
                answerForm.setAnswer("search", searchString);  
                org.jivesoftware.smackx.ReportedData data = search.getSearchResults(answerForm,"search."+mXMPPConnection.getServiceName());  

                if(data.getRows() != null)
                
                    Iterator<Row> it = data.getRows();
                    while(it.hasNext())
                    
                        Row row = it.next();
                        System.out.println(row);
                        Iterator iterator = row.getValues("jid");
                        if(iterator.hasNext())
                        
                            String value = iterator.next().toString();
                            l.add(value);
                            System.out.println("Iteartor values......"+value);
                        
                        //Log.i("Iteartor values......"," "+value);
                    
                    System.out.println("UserName Exists");

                
             catch (Exception e) 
                System.out.println("Exception in Loading user search"+e);
            
            return l;
        

【讨论】:

降级者:降级前请评论。它对我来说是可行的解决方案。 在 searchString 中放什么?我给了我的用户名,但它返回了这个异常 java.lang.ClassCastException: org.jivesoftware.smack.packet.DefaultPacketExtension 无法转换为 org.jivesoftware.smackx.packet.DataForm @MuneebMirza:搜索字符串只是部分用户名。请检查您导入的库 请告诉我这个特定操作的库名称。

以上是关于在 Android 中使用 xmpp/UserSearchManager 搜索现有用户的主要内容,如果未能解决你的问题,请参考以下文章

如何在 android 应用程序中使用 OSM 地图。?有啥教程可以学习在android中使用OSM吗?

如何在Mac中使用Android SDK

在 Android 中使用 Intent 在活动中传递 android 位图数据

无法在 Android 中使用 Android Crop 图像裁剪库

Android:如何在 Android 中使用 tensorflow lite 扩展图像的维度

如何在android中使用WCF服务?