title: How do I make my Android ContentObserver for ContactsContract detect a added, updated or deleted contact?
body: <p>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.</p>
  
  <p>Here is the code stub:</p>
  
  <pre><code>            if ((mNativeContactsObserver == null) &amp;&amp; (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) 
                                  &amp;&amp; (!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);
  </code></pre>