androidandroid-contentprovidercontentobserver

ContentObserver should call if and only if ContactsContract.Contacts.CONTENT_URI changes


As my application uses content from android.provider.ContactsContract.Data (API > 11) and ContactsContract.Contacts.CONTENT_URI (API < 11) to populate Contacts.

I've tried to registerContentObserver() against these provider. But it calls my ContentObserver even if I tries to Call a person from device as soon as I put the call. It does trigger my ContentObserver which is not useful for me as there's no Content Change in Contacts Provider.

Root Cause:

Seems like LAST_TIME_CONTACTED or something in ContactsContract.Contacts.CONTENT_URI do changes when a call has been made from device which legitimate wokes up by ContentObserver.

Tried:

private class ContactsContentObserver extends ContentObserver {
    public ContactsContentObserver() {
        super(null);
    }

    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        Zname.getPreferences().setRefreshContact(true);
    }
}

Registered ContentObserver in OnCreate() of Activity

ContactsContentObserver contactsContentObserver = new ContactsContentObserver();
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, false, contactsContentObserver);

Tried with notifyForDescendents as false on registerContentObserver. Still it triggers out ContentObserver

Ques:

How can one register ContentObserver which triggers if and only if contacts information is under CRUD(Create,Update,Delete) except Last_Time_Contacted or its descendants?


Solution

  • As android.provider.ContactsContract content provider has it's own complexity which makes ContentObserver tough to notify only on contacts content change except it's LAST_TIME_CONTACTED field as every fellow come across say these and so it is.

    One need to develop it's own logic whether contacts data get updated or not when ContentObserver notifies.

    Points to consider building logic whether contacts really get updated or not.

    Sync Phone Book Logic :- As I've maintained contacts using SQLite, so checking up whether that exist or not and w.r.t building logic.

    ContentValues values;
    Cursor cursor = Zname.getApplication().getContentResolver().query(DBConstant.All_Contacts_Columns.CONTENT_URI,null,DBConstant.All_Contacts_Columns.COLUMN_CONTACT_NUMBER+ "=?",new String[] { _contact.getContactNumber() },null);
    
     if (cursor.getCount() <= 0) {
            cursor.moveToFirst();
            Zname.getApplication().getContentResolver().delete(DBConstant.All_Contacts_Columns.CONTENT_URI,DBConstant.All_Contacts_Columns.COLUMN_CONTACT_NUMBER+ "?=",new String[] { _contact.getContactNumber() });
            Log.i(TAG, "Updating zname phonebook");
            values = new ContentValues();
            values.put(DBConstant.All_Contacts_Columns.COLUMN_CONTACT_ID,_contact.getContactId());
            values.put(DBConstant.All_Contacts_Columns.COLUMN_CONTACT_NUMBER,_contact.getContactNumber());
            values.put(DBConstant.All_Contacts_Columns.COLUMN_DISPLAY_NAME,_contact.getContactName());
            values.put(DBConstant.All_Contacts_Columns.COLUMN_ZNAME_DP_URL_SMALL,_contact.getContactPhotoUri().toString());
    
            Zname.getApplication().getContentResolver().insert(DBConstant.All_Contacts_Columns.CONTENT_URI,values);
    
            if (cursor != null)
                  cursor.close();
       }