Querying Contacts with Partial Data

I've been trying to replicate some of the OEM dialer app behaviors regarding contact matching without much luck. Basically, I'd like to populate a list of potential contact matches as the user types numbers into the dialer that match the typed entry against the phone number and the name, as most phones do. For instance, typing 323 into the dialer would match contacts that have 323 anywhere in the NUMBER, such as (323)123-4567 as well as contacts with DISPLAY_NAME of Dad or Daffy, etc.

I know that ContactsContract.PhoneLookup.CONTENT_FILTER_URI is supposed to be used to match phone numbers while ignoring formatting (so querying that uri against 5551234567 would return a contact whose number was stored as (555)123-4567). The problem is that I cannot get this to work with partial numbers, so that querying against 5551 would include the same result, even if I add selection args with a LIKE clause and wildcards. If I use any of the other URIs, the selection arg with LIKE will return partial results, but the formatting screws things up so that 5551 would not match, only 555)1 does. Can anybody explain how I might get a partial number match while ignoring formatting from a single query? Other attempts to use multiple queries have proved to be too slow and not offer the experience I see on most phones (I have noticed that the stock dialer in the Android source does not do the contact matching, only search, so no help there).

Secondly, for the name part of things, I have a working solution, although I'm not sure it is the best strategy. I had hoped to use ContactsContract.Contacts.CONTENT_FILTER_URI, as the docs say this is how you should filter results for as-you-type suggestions, but again that would only work for an alpha search of a single partial name, while I need to translate 323 to search against partial matches for all combinations of the associated keypad letters (dad, dae, daf, ead, eae, eaf, fad, etc). I have instead used ContactsContract.CommonDataKinds.Phone.CONTENT_URI with selection args using LIKE to match against all possibilities, and then subsequent requests narrow the field based on contact IDs returned from the previous request. Is there a way to leverage ContactsContract.Contacts.CONTENT_FILTER_URI for this type of numeric pattern matching? I haven't tried breaking it down to multiple requests, but based on the latency I experienced trying something similar for partial number matching described above, I suspect it would not work very well.

Any advice is much appreciated!

Thanks, Scott


I've been struggling with this for 2 days now and I finally got a solution that works as desired by myself and Scott.

You need to use this URI

ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI and append URI path which is the partial string (name or number).

Uri uri = Uri.withAppendedPath(ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI, Uri.encode(partial));
Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);

Hope this helps!


This technique works for me, to parse partial number, by using:

//encode the phone number and build the filter URI
Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number.substring(len-9)));

String selection = PhoneLookup.NUMBER + " LIKE %" + number.substring(len-9) + "%";

Cursor cursor = context.getContentResolver().query(contactUri, projection, selection, null, null);

Complete Example:

private void getContactDetails(String number) {
    // define the columns you want the query to return
    String[] projection = new String[] {
        PhoneLookup.DISPLAY_NAME,
        PhoneLookup._ID,
        PhoneLookup.LOOKUP_KEY};
    int len = number.length();
    // encode the phone number and build the filter URI
    Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number.substring(len-9)));

    String selection = PhoneLookup.NUMBER + " LIKE %" + number.substring(len-9) + "%";

    Cursor cursor = context.getContentResolver().query(contactUri, projection, selection, null, null);

    if(cursor != null) {
        if (cursor.moveToFirst()) {
            String name = cursor.getString(cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME));
            String lookUpKey = cursor.getString(cursor.getColumnIndex(PhoneLookup.LOOKUP_KEY));
        }
        cursor.close();
    }
}

It parses and matches last 10 digits of number, hope it will help !!!

链接地址: http://www.djcxy.com/p/31984.html

上一篇: 在Android上检索联系人图片

下一篇: 使用部分数据查询联系人