I have an app that gets the ContactsContract.Contacts.LOOKUP_KEY of a contact on the device and saves it on the app Db.
After reading this page I thought I could use the LOOKUP_KEY to uniquely identify a contact, even when a contact is edited (for example after editing the name of the contact).
Actually I saw that after editing a contact, its LOOKUP_KEY changes, so I cannot use anymore the LOOKUP_KEY I saved on my app DB.
My question is: is there a way to uniquely identify a contact on ContactsContract.Contacts from when it is created for the first time on the device until it is deleted from the device?
Thank you
A LOOKUP_KEY is not meant to be used as a key on its own, instead it should be used together with a contact's _ID to form a full lookupUri.
The lookupUri can then be used to find a contact in CONTENT_LOOKUP_URI tables.
The CONTENT_LOOKUP_URI basically first looks for the contact by _ID, if it fails to find it, or the _ID seems like the wrong contact, it uses hints from the LOOKUP_KEY part to try and track down the correct contact for you.
From CONTENT_LOOKUP_URI
A content:// style URI for this table that should be used to create
shortcuts or otherwise create long-term links to contacts. This URI
should always be followed by a "/" and the contact's LOOKUP_KEY. It
can optionally also have a "/" and last known contact ID appended
after that. This "complete" format is an important optimization and is
highly recommended.
As long as the contact's row ID remains the same, this URI is
equivalent to CONTENT_URI. If the contact's row ID changes as a result
of a sync or aggregation, this URI will look up the contact using
indirect information (sync IDs or constituent raw contacts).
Lookup key should be appended unencoded - it is stored in the encoded
form, ready for use in a URI.
From getLookupUri(long contactId, String lookupKey)
Build a CONTENT_LOOKUP_URI lookup Uri using the given _ID and
LOOKUP_KEY.
From LOOKUP_KEY
An opaque value that contains hints on how to find the contact if its
row id changed as a result of a sync or aggregation.
The row id (primary key) for each contact called _ID.
Related
I'm currently doing development on an Android app that requires me to read all the contacts on a device and select only specific contacts based on criteria (only contacts that have at least one valid mobile number and all email addresses linked to that contact).
I've tried the recommended approach at https://stackoverflow.com/a/19563999/3262731, but on a test device with approximately 800 contacts, retrieving all the records and then filtering takes about 17-20 seconds.
Ideally I'd love to build the criteria into a query that joins the contacts, phone, and email store tables in the contacts db as opposed to filtering in my code.
Does anyone have any suggestions please?
The android documentation seems to contain information in what you're looking for found here.
private static final String[] PROJECTION =
{
/*
* The detail data row ID. To make a ListView work,
* this column is required.
*/
Data._ID,
// The primary display name
Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ?
Data.DISPLAY_NAME_PRIMARY :
Data.DISPLAY_NAME,
// The contact's _ID, to construct a content URI
Data.CONTACT_ID
// The contact's LOOKUP_KEY, to construct a content URI
Data.LOOKUP_KEY (a permanent link to the contact
};
return new CursorLoader(getActivity(), contentUri, PROJECTION, SELECTION, SELECTION_ARGS, SORT_ORDER);
More details on how to define your criteria in the documentation. I would think this would be faster than using a ContentResolver as well.
According to http://developer.android.com/reference/android/provider/ContactsContract.Contacts.html
Query
If you need to read an individual contact, consider using CONTENT_LOOKUP_URI instead of CONTENT_URI.
If you need to look up a contact by the phone number, use PhoneLookup.CONTENT_FILTER_URI, which is optimized for this purpose.
If you need to look up a contact by partial name, e.g. to produce filter-as-you-type suggestions, use the CONTENT_FILTER_URI URI.
If you need to look up a contact by some data element like email address, nickname, etc, use a query against the ContactsContract.Data
table. The result will contain contact ID, name etc.
I want to search the contact list to get a particular contact using _ID or LOOKUP_KEY. Which one of these two is better and the reason. It will be really helpful if you give the main differences of both.
Android Doc says-
_ID - Row ID. Consider using LOOKUP_KEY instead.
LOOKUP_KEY - An opaque value that contains hints on how to find the contact if its row id changed as a result of a sync or aggregation.
So when in case the contacts RowID change for any reason LOOKUP_KEY is our way to go. Check this link on how to find it as this is not there on Docs I guess.
as far as you might know, there are contacts (aggregate contacts) which are formed by aggregation of two or more raw contacts in Android V2.x
is it possible to identify all the raw contacts from which a single aggregate contacts is formed through a query on the ContactsContract.Contacts or is there a way to identify these
contacts at all?
i could not find any flag or database field that tells me that this aggregate contacts is linked with these raw contacts.
any suggestions?
You can check AggregationExceptions.CONTENT_URI Table where relationship type are AggregationExceptions.TYPE_KEEP_TOGETHER, AggregationExceptions.TYPE_KEEP_SEPARATE, etc.
and you can find Raw_contact_id1 and raw_contact_id2.
Example of data into database. Lets say 1,2,3,4 are in relation so you can find following pairs.
Raw_contact_id1 raw_contact_id2 Relationship type
1-> 2, 1->3, 1->4, 2->3, 2->4, 3->4
A Contact cannot be created explicitly. When a raw contact is inserted, the provider will first try to find a Contact representing the same person. If one is found, the raw contact's CONTACT_ID column gets the _ID of the aggregate Contact. If no match is found, the provider automatically inserts a new Contact and puts its _ID into the CONTACT_ID column of the newly inserted raw contact.
So, while reading all the contacts one by one we can take its _ID value and can retrieve all the contacts from raw_contacts where _ID matches with raw_contacts.CONTACT_ID.
If the count is greater than 1 then we can conclude that it is linked with those numbers of contacts else it is not linked with any other contact.
I'm building an app where I need the user to select some "favorite" contacts and a phone number. I'm able to select a contact using
startActivityForResult(new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI), PICK_CONTACT_REQUEST);
and I'm able to extract all the information I need.
I then proceed to save the _id of the contact into my own database. My plan is to later list all the "favorited" contacts and display the name and phonenumber in a listview.
I want to save the contact id instead of the name and number so my listview will reflect any changes the user makes to his or her contacts.
But now I'm stuck. I don't know how to transform my table with contacts ids into a table with contact names.
I would like to something like this
my_table LEFT OUTER JOIN contacts_table ON (my_table.contact_id = contacts_table._id)
What you will want to do here is to store those IDs then when you want to pull the names from the user's address book, you'll have to cross reference the IDs with the contacts intent you have store in order to filter them out.
Basically you cant join a non-existent table (contacts_table).
You could probably just save the contect IDs however you wish, and then loop through the contact IDs and look up the contacts one-by-one extracting the data you need. If that's quick enough you wouldn't need any SQL joins ("optimize by need").
Perhaps its even quicker to use some Google API and use HTTP/XML to fetch the contacts (perhaps cache them for a while as well).
I retrieve the display name of a user via the ContactsContract API in Android.
Now I want to retrieve the given(first) name of this user. There are specific Rows in the data table that contain the name of the user. The problem is that there are multiple rows for every user because of the synchronization and aggregation of contacts.
The Contacts table documentation states that there should be column containing the id of the raw contact that contributes the primary name for this user. But there is no constant name for this column defined and I couldn't find this column inside my data table.
How do I retrieve the Id of the raw contact that contributes the DisplayName to a contact?
If I understood correctly, the "IS_PRIMARY" or the "IS_SUPER_PRIMARY" flag in the RawContactsEntity-table may solve your problem.