问题
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?
回答1:
The fundamental problem here is that registering for ContactsContract.Contacts.CONTENT_URI
isn't working as you might reasonably think.
The reason why you get updates even if notifyForDescendents
is false
is because the Uri
triggering the update is... ContactsContract.Contacts.CONTENT_URI
and not the contact row that is being dialled.
The offending code in the Contacts app can be found at GrepCode and there is a bug filed for this on Google Code.
So to answer your question, you can't register a ContentObserver
which will trigger for specific fields on a contact. You would need to have something in your app which will keep track of calculating the differences whenever onChange
fires.
回答2:
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.
- Checking on these basis of Last Time checked. Depends on the requirement.
- Adding
ContentObserver
inService
which isSTICKY
so it can be there when contacts get change.
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();
}
来源:https://stackoverflow.com/questions/23783356/contentobserver-should-call-if-and-only-if-contactscontract-contacts-content-uri