Intelligent search contacts in android

Following This extraction of the contact list tutorial on the Android developers site, I managed to implement the contact search functionality. Here is my code so far

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()); } } 

Here's the catch, this code works very well, but I need to implement smart search. I want 26268 to match Amanu, as well as 094 526 2684. I believe it is called T9.

I tried to look at other projects, but did not find anything. Any pointers would be appreciated!

+5
source share
3 answers

ContentProvider for contacts does not support it. So what I did was to reset all the contacts in the List , and then use RegEx to match the name.

 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<>(); } 

.... Then compile the template. I used (?i) to make case insensitive

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

You will learn what to do after that.

0
source

A T9 search can be implemented using a trie data structure . Here you can see an example - Trie dict . After implementing something like this, you can convert your search input into its possible decoded version of T9 and compare if it matches the name.

+3
source

Reset all contacts in HashSet

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

Then do a search:

 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); 

Search Method ( 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 no input left, copy the words stack to results results.add(new ArrayList<String>(words)); } else { // there 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(); } } } 
+1
source

Source: https://habr.com/ru/post/1244850/


All Articles