问题
I am able to get a generic notification "that there was a change to the contacts DB", but I want to know the specific record that was inserted, updated, or deleted. Following is the code that gets registered and gets the onChange notification. Unfortunately, it is not specific which makes my processing exhaustive and inefficient.
Here is the code stub:
if ((mNativeContactsObserver == null) && (mHandler == null)) {
mHandler = new Handler(this.getMainLooper()) {
};
mNativeContactsObserver = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Bundle data = null;
Message message = mHandler.obtainMessage();
if (message != null) {
data = message.getData();
if (data != null) {
Logs.d(TAG, "Message = [" + message.toString() + "] data=[" + data.toString() + "]");
Logs.d(TAG, "Contents = [" + message.describeContents() + "]");
}
}
if (!selfChange) {
final Account accountListen = MySyncAdapter.lookupAccount(TAG, getApplicationContext(), getUserProfile().getAccountId(), AUTHORITY_MY_SYNC);
Logs.d(TAG, "onChange!? account: " + accountListen.name);
if (!ContentResolver.isSyncPending(account, ContactsContract.AUTHORITY)
&& (!ContentResolver.isSyncActive(account, ContactsContract.AUTHORITY))) {
Bundle extras = new Bundle();
extras.putInt(MySyncAdapter.EXTRA_SYNC_TYPE, MySyncAdapter.REQUEST_SYNC_NATIVE_CHANGED);
ContentResolver.requestSync(accountListen, ContactsContract.AUTHORITY, extras);
} else {
Logs.w(TAG, "There is a pending sync. This request is ignored.");
}
}
}
};
}
Uri uriContactsListen = ContactsContract.Contacts.CONTENT_URI.buildUpon().appendEncodedPath("#").build();
Logs.i(TAG, "Register listening for native contacts changes. [" + uriContactsListen + "]");
cr.registerContentObserver(uriContactsListen, true, mNativeContactsObserver);
回答1:
Finally at least i am able to detect is this Update/Delete/Insert look at my OnChange
method as below
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Log.e("ContactChangeObserver", "onChange");
// 0 Update , 1 Delete , 2 Added
// Get count from phone contacts
final int currentCount = contactDBOperaion.getContactsCountFromPhone();
// Get count from your sqlite database
int mContactCount= DbContacts.getInstance().getContactsCount();
if (currentCount < mContactCount) {
// DELETE HAPPEN.
Log.e("Status", "Deletion");
contactDBOperaion.SyncContacts(1);
} else if (currentCount == mContactCount) {
// UPDATE HAPPEN.
contactDBOperaion.SyncContacts(0);
} else {
// INSERT HAPPEN.
Log.e("Status", "Insertion");
contactDBOperaion.SyncContacts(2);
}
}
When Update occurred i update all contacts
When Insert occurred i am inserting newly added row , after checking isExist in existing database
When Delete occurred not found solution yet
回答2:
I have this code in my Application base class.
private ContentObserver contactObserver = new ContactObserver();
private class ContactObserver extends ContentObserver {
public ContactObserver() {
super(null);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
// Since onChange do not sent which user have been changed, you
// have to figure out how to match it with your data.
// Note: Contact is one of my classes.
for (Contact contact : getContacts()) {
if (!contact.isLinked())
continue;
String selection = ContactsContract.Data._ID + " = ?";
String[] selectionArgs = new String[] { contact.getSystemId() };
String[] projection = new String[] { ContactsContract.Data.DISPLAY_NAME };
Cursor cursor = getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI, projection,
selection, selectionArgs, null);
if (!cursor.moveToFirst())
return;
String name = cursor.getString(0);
if (contact.getUsername().equalsIgnoreCase(name))
continue;
contact.setUserName(name);
}
}
}
Regarding about what you can put in projection check here
Unfortunately, it is not specific which makes my processing exhaustive and inefficient.
Would be great if into next Android releases also will send the contact id which had been just changed.
Hope this helps
回答3:
First of all, you have to register your contentObserver to receive change notification.
Do this by calling :
registerContentObserver();
Here's the specs : registerContetObserver
After than you'll want to notify all the listeners when a modification happens :
contentResolver.notifyChange();
Here's the specs for that one : notifyChange
Hope it helps ;)
Cheers !
回答4:
Use Loaders to query and display the list of contacts on your android device on your emulator. They automatically detect changes in the underlying data and reflect that on your UI.
来源:https://stackoverflow.com/questions/5996921/how-do-i-make-my-android-contentobserver-for-contactscontract-detect-a-added-up