java - proyectos - Entendiendo la arquitectura de los contactos de Android
manual programacion android (2)
Estoy desarrollando una aplicación para Android que necesita saber cuándo se agrega / actualiza / elimina un contacto.
Así que leí varias publicaciones para ello. Entiendo que podemos recibir notificaciones a través de observadores de Contenido cada vez que se modifique un contacto, pero no podemos saber qué contactos se han agregado / actualizado / eliminado. Así que leí las API oficiales y preparé mi diseño sobre cómo capturar ese contacto en particular.
Así que lo que pensé al principio.
- Almacenaremos todos los identificadores de contacto, bandera eliminada y versión
- Cuando los contactos cambien, obtendré el conteo de filas de mi mesa y el conteo de filas del sistema de Android.
- Si mi recuento de filas es menor que el número de filas de los sistemas, se eliminó un contacto.
- Si mi conteo de filas es mayor que el conteo de filas de los sistemas, entonces se agregó un contacto.
- Y si estos no son los casos, entonces se ha cambiado una de las versiones de contactos.
También aprendí que Android no elimina el contacto si el usuario lo elimina, pero establece un 0 en la marca eliminada. Así que en estos casos el conteo de filas será el mismo.
Android también cambia el ID de fila de un contacto muchas veces como se indica en los documentos oficiales. Entonces, ¿cómo podemos identificarlos de forma única como búsqueda de uri y, de no ser así, también tenemos que poner un observador para eso?
¿Entonces quiero saber si lo anterior es correcto? Y en el caso de que se agregue un contacto, se agregará a la última fila del cursor o no significa que si reviso la última fila de la base de datos del sistema en busca de contactos, me dará el contacto agregado o no.
Creo que la mejor práctica es monitorear cada vez que un contacto se agregue a otro e identificarlos por contactName, no por _ID o CONTACT_ID. Eche un vistazo a esta posible operación de contactos:
Insertar
Un contacto no puede ser creado explícitamente. Cuando se inserta un contacto sin procesar, el proveedor primero intentará encontrar un contacto que represente a la misma persona. Si se encuentra uno, la columna CONTACT_ID del contacto sin formato obtiene el _ID del contacto agregado. Si no se encuentra una coincidencia, el proveedor inserta automáticamente un nuevo contacto y coloca su _ID en la columna CONTACT_ID del contacto sin tratar recién insertado.
Actualizar
Solo ciertas columnas de contacto son modificables: TIMES_CONTACTED, LAST_TIME_CONTACTED, STARRED, CUSTOM_RINGTONE, SEND_TO_VOICEMAIL. Cambiar cualquiera de estas columnas en el Contacto también las cambia en todos los contactos en bruto constituyentes.
Borrar
¡Tenga cuidado al eliminar contactos! Al eliminar un contacto agregado, se eliminan todos los contactos en bruto constituyentes. Los adaptadores de sincronización correspondientes notarán las eliminaciones de sus respectivos contactos sin procesar y los eliminarán de su almacenamiento final.
Consulta
Si necesitas leer un contacto individual, considera usar CONTENT_LOOKUP_URI en lugar de CONTENT_URI. Si necesita buscar un contacto por el número de teléfono, use PhoneLookup.CONTENT_FILTER_URI, que está optimizado para este propósito. Si necesita buscar un contacto por nombre parcial, por ejemplo, para producir sugerencias de filtro a medida que escribe, use el URI CONTENT_FILTER_URI. Si necesita buscar un contacto por algún elemento de datos como la dirección de correo electrónico, el apodo, etc., utilice una consulta en la tabla ContactsContract.Data. El resultado contendrá ID de contacto, nombre, etc.
El problema, sin embargo, es que podría tener dos ''Phillip Morris'' en su lista de contactos que no son la misma persona.
Para más información, consulte ContactsContract.Contacts de la documentación de clases de Android.
Déjame explicarte todo lo que pueda. Básicamente, su política se ve bastante bien, pero en realidad es un poco más compleja de lo que pensaba.
En Android, un contacto puede asociarse con varios contactos sin procesar , que pueden proporcionar muchos proveedores de datos, como Google, Facebook, Skype, etc. Por ejemplo, si uno de tus amigos en tus contactos locales también está usando Skype, hay dos contactos sin procesar que existen por separado en ContactContracts.RawContacts
, pero se agregarán automáticamente y se mostrarán como un solo contacto cuando consultes a ContactsContract.Contacts
.
Por eso también es difícil identificar un contacto de forma única, ya que puedes dividirte o unirte en cualquier momento que desees. LOOKUP_KEY
no es muy útil para este caso.
Muchas aplicaciones, excepto Google, solo proporcionan una sincronización unidireccional, es decir , solo desde el servicio hasta los contactos, por lo que son de solo lectura. En este caso, la bandera eliminada no se utilizará y simplemente se eliminará durante su proceso de sincronización. Por lo tanto, no se puede simplemente confiar en la bandera.
Aunque no hay una buena solución simple, supongo que es mucho más fácil lograr lo que quieres, si observas para un RawContacts
específico, no Contacts
. Espero que esto ayude a su comprensión.