¿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.