/** * Configures the query string to be used to find SmartDial matches. * * @param query The query string user typed. */ public void configureQuery(String query, boolean isSmartQuery) { LogUtils.d(TAG, "MTK-DialerSearch, Configure new query to be " + query); if (isSmartQuery) { mQuery = SmartDialNameMatcher.normalizeNumber(query, SmartDialPrefix.getMap()); } else { mQuery = query; if (DialerSearchUtils.isInValidDialpadString(mQuery)) { mRegularSearch = true; } } mContactsPrefs = new ContactsPreferences(mContext); }
@Override public void onDialpadQueryChanged(String query) { final String normalizedQuery = SmartDialNameMatcher.normalizeNumber(query, SmartDialNameMatcher.LATIN_SMART_DIAL_MAP); if (!TextUtils.equals(mSearchView.getText(), normalizedQuery)) { if (DEBUG) { Log.d(TAG, "onDialpadQueryChanged - new query: " + query); } if (mDialpadFragment == null || !mDialpadFragment.isVisible()) { // This callback can happen if the dialpad fragment is recreated because of // activity destruction. In that case, don't update the search view because // that would bring the user back to the search fragment regardless of the // previous state of the application. Instead, just return here and let the // fragment manager correctly figure out whatever fragment was last displayed. return; } mSearchView.setText(normalizedQuery); } }
/** * Returns a list of candidate contacts where the query is a prefix of the dialpad index of the * contact's name or phone number. * * @param query The prefix of a contact's dialpad index. * @return A list of top candidate contacts that will be suggested to user to match their input. */ public ArrayList<ContactNumber> getLooseMatches(String query, SmartDialNameMatcher nameMatcher) { final boolean inUpdate = sInUpdate.get(); if (inUpdate) { return Lists.newArrayList(); } final SQLiteDatabase db = getReadableDatabase(); /** Uses SQL query wildcard '%' to represent prefix matching. */ final String looseQuery = query + "%"; final ArrayList<ContactNumber> result = Lists.newArrayList(); final StopWatch stopWatch = DEBUG ? StopWatch.start(":Name Prefix query") : null; final String currentTimeStamp = Long.toString(System.currentTimeMillis()); /** Queries the database to find contacts that have an index matching the query prefix. */ final Cursor cursor = db.rawQuery( "SELECT " + SmartDialDbColumns.DATA_ID + ", " + SmartDialDbColumns.DISPLAY_NAME_PRIMARY + ", " + SmartDialDbColumns.PHOTO_ID + ", " + SmartDialDbColumns.NUMBER + ", " + SmartDialDbColumns.CONTACT_ID + ", " + SmartDialDbColumns.LOOKUP_KEY + " FROM " + Tables.SMARTDIAL_TABLE + " WHERE " + SmartDialDbColumns.CONTACT_ID + " IN " + " (SELECT " + PrefixColumns.CONTACT_ID + " FROM " + Tables.PREFIX_TABLE + " WHERE " + Tables.PREFIX_TABLE + "." + PrefixColumns.PREFIX + " LIKE '" + looseQuery + "')" + " ORDER BY " + SmartDialSortingOrder.SORT_ORDER, new String[] {currentTimeStamp}); if (DEBUG) { stopWatch.lap("Prefix query completed"); } /** Gets the column ID from the cursor. */ final int columnDataId = 0; final int columnDisplayNamePrimary = 1; final int columnPhotoId = 2; final int columnNumber = 3; final int columnId = 4; final int columnLookupKey = 5; if (DEBUG) { stopWatch.lap("Found column IDs"); } final Set<ContactMatch> duplicates = new HashSet<ContactMatch>(); int counter = 0; try { if (DEBUG) { stopWatch.lap("Moved cursor to start"); } /** Iterates the cursor to find top contact suggestions without duplication. */ while ((cursor.moveToNext()) && (counter < MAX_ENTRIES)) { final long dataID = cursor.getLong(columnDataId); final String displayName = cursor.getString(columnDisplayNamePrimary); final String phoneNumber = cursor.getString(columnNumber); final long id = cursor.getLong(columnId); final long photoId = cursor.getLong(columnPhotoId); final String lookupKey = cursor.getString(columnLookupKey); /** * If a contact already exists and another phone number of the contact is being processed, * skip the second instance. */ final ContactMatch contactMatch = new ContactMatch(lookupKey, id); if (duplicates.contains(contactMatch)) { continue; } /** * If the contact has either the name or number that matches the query, add to the result. */ final boolean nameMatches = nameMatcher.matches(displayName); final boolean numberMatches = (nameMatcher.matchesNumber(phoneNumber, query) != null); if (nameMatches || numberMatches) { /** If a contact has not been added, add it to the result and the hash set. */ duplicates.add(contactMatch); result.add(new ContactNumber(id, dataID, displayName, phoneNumber, lookupKey, photoId)); counter++; if (DEBUG) { stopWatch.lap("Added one result"); } } } if (DEBUG) { stopWatch.stopAndLog(TAG + "Finished loading cursor", 0); } } finally { cursor.close(); } return result; }