Интеллектуальные поисковые контакты в android

Следуя этому руководству по извлечению списка контактов на сайте разработчиков Android, мне удалось реализовать функциональность поиска контактов. Вот мой код до сих пор

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 dictionary.

Я попытался взглянуть на другие проекты, но ничего не нашел. Любые указатели будут оценены!

    Поиск T9 может быть реализован с использованием структуры данных trie . Здесь вы можете увидеть пример – Trie dict . После реализации чего-то подобного вы сможете преобразовать свой поиск в свой возможный вариант декодирования T9 и сравнить, если он совпадает с именем.

    Сбросить все контакты в 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); 

    Метод поиска ( из @ 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(); } } } 

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

    Вы узнаете, что делать после этого.