Detecting Changes in Android Contacts
- Get link
- X
- Other Apps
Introduction
In this post, we'll explore how to detect changes in Android contacts. Android OS provides a mechanism for contact storage known as the Contacts Provider. This provider offers a structured set of data and a standard interface that connects data across different processes.
Structure of Android Contacts
ContactsRaw Table
- _id: RAW_CONTACT_ID
- account_name: e.g., email address
- account_type: e.g., com.google.com
- deleted: Indicates if the contact is deleted
The ContactsContract.RawContacts.CONTENT_URI
table contains original contacts, mainly storing RAW_CONTACT_ID
. Contact details are stored in the ContactsContract.Data
table.
Contacts Table
- _id: CONTACT_ID (refers to a group of
RAW_CONTACT_ID
s) - lookup: Provides a link to all contact details in this table
The Contacts.CONTENT_URI
table groups RawContacts
based on merging rules. If a raw contact can't be grouped with an existing contact, a new contact is created. The LOOKUP_KEY
is a permanent link to a contact, remaining consistent even if CONTACT_ID
changes due to merging.
ContactContract Table
- _id: CONTACT_DETAIL_ID
- lookup: Permanent link to contact
- raw_contact_id: Refers to
RAW_CONTACT_ID
in theContactsRaw
table - contact_id: Refers to
CONTACT_ID
in theContacts
table - version: Reflects updates to contact records
- data1 to data16: Data content (e.g., email, phone number, address)
- mime_type: Type of record (e.g., email, number, address)
- is_primary: Indicates if there are multiple instances of contact information (e.g., primary phone number)
The ContactsContract.Data.CONTENT_URI
table contains contact details. Each contact may have multiple records here (e.g., one for name, one for phone number, one for email). contact_id
is a reference to the Contacts
table, and raw_contact_id
references the original contact.
AggregationException Table
- RAW_CONTACT_ID1: First raw contact ID
- RAW_CONTACT_ID2: Second raw contact ID
- AggregationExceptions.TYPE: Type of exception (e.g., automatic merging, keeping separate, keeping together)
The AggregationException
table specifies pairs of raw contacts that should not be grouped. The type can be:
TYPE_AUTOMATIC
: Automatic merging by the content providerTYPE_KEEP_SEPARATE
: Contacts remain separateTYPE_KEEP_TOGETHER
: Contacts are merged until explicitly separated by the user
Automatic Merging Rules
Contacts are merged automatically based on:
- Matching name and surname
- Matching name and surname in different orders
- Matching surname and a short first name
- Matching name or surname with one phone/email
- One contact lacking a name/surname but sharing a phone/email
Detecting Changes
Using ContentObserver
To detect contact changes, you can use ContentObserver
, which provides two methods:
onChange(boolean selfChange)
: Triggers when something changesonChange(boolean selfChange, Uri uri)
: Provides the URI of the changed contact (available since API 16)
Version Number
Each contact record includes a version number. By maintaining a local database of stored versions, you can compare version numbers to detect changes.
Timestamp
You can track the last change using a timestamp (available since API 18). By querying with this timestamp, you can identify which contacts have been modified.
Detecting New Contacts
To detect new contacts, save the last RAW_CONTACT_ID
and query for contacts with higher IDs. When a significant change occurs, a new RAW_CONTACT_ID
is generated. Check
for changes in the LOOKUP_KEY
to ensure you’re capturing all updates accurately.
Detecting Removed Contacts
To determine if a contact has been removed, query the database for the contact using the LOOKUP_KEY
. This process might be resource-intensive as it involves checking each contact of interest.
SyncAdapter and Server Synchronization
The Contacts Provider is designed to handle synchronization between a device and an online service. A SyncAdapter can be used to manage contact synchronization with your custom account and server. This component handles tasks such as checking network availability, scheduling, and restarting synchronization, which can be useful for applications involving contact management.
Issues Encountered
During synchronization, I encountered an issue where updating a contact (replacing its content) led to the contact being removed and a new one being created with a different RAW_CONTACT_ID
. According to the documentation, this happens if the raw contact changes significantly. Despite attempts to reproduce this issue through both simple queries and batch operations, I couldn't replicate it consistently.
What Would Be Great?
A feature that would significantly enhance contact management would be a listener that notifies which contacts (including third-party accounts) are new, deleted, or changed. Additionally, a history feature that allows querying changes since a specific timestamp would be very beneficial.
Helpful Links
This article was written to help me remember the details of working with Android contacts. If you find any inaccuracies or have additional insights, please leave a comment below.
- Get link
- X
- Other Apps
Comments
Post a Comment