Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android contacts: How does the lookup key works?

On top of contacts id, Android also got LOOK_UP key. Since id of contact can change, you can obtain user uri, using LOOK_UP key.

public static Uri lookupContactUri(String lookup, Context context){
    ContentResolver contentResolver = context.getContentResolver();
    Uri lookupUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookup);
    return ContactsContract.Contacts.lookupContact(contentResolver, lookupUri);
}

But how does it work? The source code of the Contacts.lookupContact doesn't tell much about the actual implementation. So can anyone explain how does they manage to pull this up?

    /**
     * Computes a content URI (see {@link #CONTENT_URI}) given a lookup URI.
     * <p>
     * Returns null if the contact cannot be found.
     */
    public static Uri lookupContact(ContentResolver resolver, Uri lookupUri) {
        if (lookupUri == null) {
            return null;
        }

        Cursor c = resolver.query(lookupUri, new String[]{Contacts._ID}, null, null, null);
        if (c == null) {
            return null;
        }

        try {
            if (c.moveToFirst()) {
                long contactId = c.getLong(0);
                return ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
            }
        } finally {
            c.close();
        }
        return null;
    }

Another thing I tested, is merging two contacts using ContactsContract.AggregationExceptions and then quarrying for contact uri. Both of the LOOK_UP keys yield with the same contact uri as expected.

So how are they doing it?

like image 837
Ilya Gazman Avatar asked Feb 20 '17 04:02

Ilya Gazman


1 Answers

Since contact ids can change from time to time (e.g. when contacts sync is corrupted and contacts needs to be resynced from server), Android introduced the concept of LookupKeys and LookupUris.

A LookupKey is an opaque value, that internally can be translated by the Contacts framework to a set of fields: contact-id, raw-contact-ids, primary-display-names, etc.

Whenever you try to access a contact via a LookupUri, the system, extracts the LookupKey from the Uri, tries to access the contact-id, and compares the other fields (raw-ids, names, etc.) to the found contact, if it seems the right contact, it returns it. If the contact-id wasn't found, or the system detects it's the wrong contact, a query is made over all contacts to find the right one (using the auxiliary fields stored on that key).

So the LookupKey acts as a quick method to either return the contact-id, or search for it in case something bad happened.

like image 69
marmor Avatar answered Sep 22 '22 22:09

marmor