android crud contactscontract contentobserver

¿Cómo hago que mi ContentObserver para ContactsContract de Android detecte un contacto agregado, actualizado o eliminado?



crud (4)

Puedo recibir una notificación genérica "de que hubo un cambio en la base de datos de contactos", pero quiero saber el registro específico que se insertó, actualizó o eliminó. A continuación se muestra el código que se registra y recibe la notificación onChange. Desafortunadamente, no es específico lo que hace que mi procesamiento sea exhaustivo e ineficiente.

Aquí está el código auxiliar:

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);


En primer lugar, debe registrar su contentObserver para recibir una notificación de cambio.

Haga esto llamando

registerContentObserver();

Aquí están las especificaciones: registerContetObserver

Después de eso, querrá notificar a todos los oyentes cuando ocurra una modificación:

contentResolver.notifyChange();

Aquí están las especificaciones para eso: notifyChange

Espero eso ayude ;)

Saludos!


Finalmente, al menos puedo detectar esta actualización / Eliminar / Insertar mi método OnChange como se muestra a continuación

@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); } }

Cuando se produjo la actualización actualizo todos los contactos

Cuando ocurrió la inserción, estoy insertando la fila recién agregada, después de verificar isExist en la base de datos existente

Cuando se produjo el borrado no se encontró la solución


Tengo este código en mi clase base de aplicación.

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); } } }

En cuanto a lo que puedes poner en proyección verifica here

Unfortunately, it is not specific which makes my processing exhaustive and inefficient.

Sería genial si en las próximas versiones de Android también se envíe el ID de contacto que se acaba de cambiar.

Espero que esto ayude


Utilice los cargadores para consultar y mostrar la lista de contactos en su dispositivo Android en su emulador. Detectan automáticamente los cambios en los datos subyacentes y reflejan eso en su interfaz de usuario.