【问题标题】:Smart searching contacts in android安卓智能搜索联系人
【发布时间】:2016-06-25 22:54:09
【问题描述】:

在 android 开发者网站上This Retrieving a List of Contacts Tutorial 之后,我设法实现了联系人搜索功能。到目前为止,这是我的代码

private void retrieveContactRecord(String phoneNo) {
        try {
            Log.e("Info", "Input: " + phoneNo);
            Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
                    Uri.encode(phoneNo));
            String[] projection = new String[]{ContactsContract.PhoneLookup._ID, ContactsContract.PhoneLookup.DISPLAY_NAME};


            String sortOrder = ContactsContract.PhoneLookup.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
            ContentResolver cr = getContentResolver();
            if (cr != null) {
                Cursor resultCur = cr.query(uri, projection, null, null, sortOrder);
                if (resultCur != null) {
                    while (resultCur.moveToNext()) {
                        String contactId = resultCur.getString(resultCur.getColumnIndex(ContactsContract.PhoneLookup._ID));
                        String contactName = resultCur.getString(resultCur.getColumnIndexOrThrow(ContactsContract.PhoneLookup.DISPLAY_NAME));
                        Log.e("Info", "Contact Id : " + contactId);
                        Log.e("Info", "Contact Display Name : " + contactName);
                        break;
                    }
                    resultCur.close();
                }
            }
        } catch (Exception sfg) {
            Log.e("Error", "Error in loadContactRecord : " + sfg.toString());
        }
    }

这里有一个问题,这段代码工作得很好,但我需要在这里实现一个智能搜索。 我希望 26268 匹配 Amanu 以及 094 526 2684。我相信它被称为 T9 字典。

我尝试查看其他项目以寻找线索,但我找不到任何东西。任何指针将不胜感激!

【问题讨论】:

    标签: android search android-contacts t9


    【解决方案1】:

    T9 搜索可以使用trie data structure 实现。您可以在此处查看示例 - Trie dict。 在实现类似的东西之后,您将能够将您的搜索输入转换为其可能的 T9 解码变体,并比较它是否与名称匹配。

    【讨论】:

    • 你实现了吗? ,我无法理解如何在我的项目中使用请帮助
    【解决方案2】:

    将所有联系人转储到 HashSet

    Set<String> contacts = new HashSet<String>();
    

    然后搜索:

    List<List<String>> results = new ArrayList<List<String>>();
    // start the search, pass empty stack to represent words found so far
    search(input, dictionary, new Stack<String>(), results);
    

    搜索方式(from @WhiteFang34

    public static void search(String input, Set<String> contacts,
        Stack<String> words, List<List<String>> results) {
    
        for (int i = 0; i < input.length(); i++) {
            // take the first i characters of the input and see if it is a word
            String substring = input.substring(0, i + 1);
    
            if (contacts.contains(substring)) {
                // the beginning of the input matches a word, store on stack
                words.push(substring);
    
                if (i == input.length() - 1) {
                    // there's no input left, copy the words stack to results
                    results.add(new ArrayList<String>(words));
                } else {
                    // there's more input left, search the remaining part
                    search(input.substring(i + 1), contacts, words, results);
                }
    
                // pop the matched word back off so we can move onto the next i
                words.pop();
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      联系人的ContentProvider 不支持它。所以我所做的是将所有联系人转储到 List 中,然后使用 RegEx 匹配名称。

      public static String[] values = new String[]{" 0", "1", "ABC2", "DEF3", "GHI4", "JKL5", "MNO6", "PQRS7", "TUV8", "WXYZ9"};
      
      /**
       * Get the possible pattern
       * You'll get something like ["2ABC","4GHI"] for input "14"
       */
      public static List<String> possibleValues(String in) {
      
          if (in.length() >= 1) {
              List<String> p = possibleValues(in.substring(1));
              String s = "" + in.charAt(0);
              if (s.matches("[0-9]")) {
                  int n = Integer.parseInt(s);
      
                  p.add(0, values[n]);
              } else {
                  // It is a character, use it as it is
                  p.add(s);
              }
      
              return p;
          }
          return new ArrayList<>();
      }
      

      .... 然后编译模式。我使用(?i) 使其不区分大小写

      List<String> values = Utils.possibleValues(query);
      StringBuilder sb = new StringBuilder();
      for (String value : values) {
          sb.append("[");
          sb.append(value);
          sb.append("]");
          if (values.get(values.size() - 1) != value) {
          sb.append("\\s*");
          }
      }
      
      Log.e("Utils", "Pattern = " + sb.toString());
      
      Pattern queryPattern = Pattern.compile("(?i)(" + sb.toString() + ")");
      

      之后你会知道该怎么做。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-11
        • 2011-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多