简体   繁体   中英

Should I rely on SOURCE_ID when reading Android Contacts?

I am creating an android contacts app, so I regularly read user's contacts and store them in my app. To do this, I need to rely on some kind of ID so that I know which contact I should update (or add/delete) in my app and Contacts Provider supplies several of them:

  • CONTACT_ID is the aggregate contact id,
  • each aggregate contact consists of one or more Raw Contacts, each with its own RAW_CONTACT_ID ,
  • and most important, each Raw Contact has a SOURCE_ID , which is supposed to be the server id, ie the id this contact has in this account's server.

I 've chosen to rely on SOURCE_ID , since this sounds like the most stable one. Eg when user removes and re-adds the same account in their device, I wouldn't want this account's contacts to get different IDs, because I wouldn't be able to match them in my app.

However , only Gmail sync adapter seems to keep the promise documented below. Exchange sync adapters unfortunately do not, SOURCE_ID changes, and it's definitely not any server id, since it has a small number like 23:4 .

Question : Any ideas how to overcome this problem? Am I using the right ID for the intended use? Does exchange adapter stores the "permanent server id" in some other field?

Documentation : The SOURCE_ID must be unique for each account type and should be stable across syncs :

  • Unique: Each raw contact for an account must have its own source id. If you don't enforce this, you'll cause problems in the contacts application. Notice that two raw contacts for the same account type may have the same source id. For example, the raw contact "Thomas Higginson" for the account emily.dickinson@gmail.com is allowed to have the same source id as the raw contact "Thomas Higginson" for the account emilyd@gmail.com.
  • Stable: Source ids are a permanent part of the online service's data for the raw contact. For example, if the user clears Contacts Storage from the Apps settings and re-syncs, the restored raw contacts should have the same source ids as before. If you don't enforce this, shortcuts will stop working.

LOOKUP_KEY is what you're looking for.

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.

You should use a pair of <CONTACT_ID, LOOKUP_KEY> to keep track of contacts. In normal use, use the CONTACT_ID value, but if your code gets a hint that the CONTACT_ID has changed (either missing, or unexpected contact name), you can use the LOOKUP_KEY to find the new contact-id.

Or you can use Contacts.getLookupUri() to get a URI you can always use to quickly find a contact no matter what its CONTACT_ID or LOOKUP_KEY actual values are.

First thing, it's not a good idea to store the Id in your application and hoping that the Id won't change over time and be consistent. You are right about ' SOURCE_ID ' column that it's more consistent compared to the other two ( CONTACT_ID is the most brittle while ' RAW_CONTACT_ID ' persists at least until user logs out of an account and logs in again).

We had a syncable account with contacts and we used to keep the unique id in one of the general purpose columns in the ' raw_contacts ' table (SYNC1 - SYNC10). So although Google suggests that account providers use the database columns in a certain manner but it's upto the provider totally.

General rule to follow is, never use those id's for long term persistence and if you do so, expect them to change. Also since you are making a contact App, you obviously need some kind of reference key. In such case, don't go by the rule that all account providers will put their key in the same column. It's brittle but that's the way it is.

Edit - You should use ContactsColumns.LOOKUP_KEY (previous answer also cited the same). As per the Google Documentation -

LOOKUP_KEY

Added in API level 5 String 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.

Constant Value: "lookup"

https://developer.android.com/reference/android/provider/ContactsContract.ContactsColumns.html#LOOKUP_KEY

You can fetch the lookup key if you have the contact Id using API's provided. Look here - https://developer.android.com/reference/android/provider/ContactsContract.Contacts.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM