I would like to clone Android Contacts Phone into my own SQLite db. In order to save time, the cloning should be triggered when the single contact is newly created or being updated in the Android system. Thus, I want to have "last modified time" of each contact.
For API level 18 or above, it seems that i would get the last modified time of a single person contact by using ContactsContract.Contacts.CONTACT_LAST_UPDATED_TIMESTAMP. However for API Level 17 or below, it seems that there are some discussions before which suggested the use of "ContactsContract.RawContacts.VERSION" or "CONTACT_STATUS_TIMESTAMP".
For "CONTACT_STATUS_TIMESTAMP", it always returns ZERO or null. For "ContactsContract.RawContacts.VERSION", the version remained the same when i updated the photo, phone number or email of a person's contact.
Glad if someone would point out the mistakes i have made...
Reference: How to get the last modification date for Contacts list (Add/Delete/Modify)
You can get notified when something changes using a ContentObserver. You will then need to retrieve the correct contact yourself. Of course that means having to have your app open when the contact changes or (more reasonably) running a background service.
In your service, create a content observer:
myObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
if (!selfChange) {
//Note: when this (older) callback is used you need to loop through
//and find the contact yourself (by using the dirty field)
}
}
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
if (!selfChange) {
//Note: if you receive a uri, it has contact id
long rawContactId = ContentUris.parseId(uri);
//Note: be careful which thread you are on here (dependent on handler)
}
}
};
//NOTE: Then you need to remember to register and unregister the observer.
//getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, myObserver);
//getContentResolver().unregisterContentObserver(myObserver);
Your suggestion to use dirty is not a good solution alone, as this only temporarily indicates that the aggregate contact (owner) should be updated because something in the RawContact changed. This means if the contact gets synced before your app gets opened, dirty is already false (0) again.
Also note that the documentation for the column mentions that it was added in API 18, so as you are aware, it is only below 18 that you need a workaround. so the first step is to make sure you are using the column when you can
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
//continue with existing code
} else {
//use workaround (start service, or at least register observer)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With