安卓智能搜索联系人

Posted

技术标签:

【中文标题】安卓智能搜索联系人【英文标题】: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 字典。

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

【问题讨论】:

【参考方案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() + ")");

之后你会知道该怎么做。

【讨论】:

以上是关于安卓智能搜索联系人的主要内容,如果未能解决你的问题,请参考以下文章

VirusTotal智能搜索安卓样本示例

安卓智能手机怎样导入通信录/联系人

大数据时代的商业智能

搜索引擎文本分类

markdown 智能代码搜索源代码搜索智能[jetbrains]

生活中的人工智能之搜索和推荐算法