将android联系人与服务器同步

将android联系人与服务器同步,android,synchronization,android-contacts,Android,Synchronization,Android Contacts,我正在创建一个android应用程序,用于跟踪设备上保存的所有联系人(默认android联系人应用程序中显示的联系人),并将其保存在服务器上的MySQL表中 我使用ContectResolver读取了所有联系人数据: //to read only android address book String where = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '1'"; String[] projection =

我正在创建一个android应用程序,用于跟踪设备上保存的所有联系人(默认android联系人应用程序中显示的联系人),并将其保存在服务器上的MySQL表中

我使用
ContectResolver
读取了所有联系人数据:

    //to read only android address book
    String where = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '1'";

    String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY, ContactsContract.Contacts.HAS_PHONE_NUMBER};

    ContentResolver cr = context.getContentResolver();
    Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, projection, where, null, null);
然后,使用
Contacts Contacts.Contacts.\u ID
I查询其他联系人数据:

// Perform a query to retrieve the contact's name parts
        String[] nameProjection = new String[] {
                ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,
                ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME,
                ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME,
                ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME
        };

        Cursor nameCursor = cr.query(
                ContactsContract.Data.CONTENT_URI,
                nameProjection,
                ContactsContract.Data.MIMETYPE + " = '" +
                        ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "' AND " +
                        ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID
                        + " = ?", new String[] { id }, null);

        // Retrieve the name parts
        String firstName = "", middleName = "", lastName = "", displayName = "";
        if(nameCursor.moveToNext()) {
            firstName = nameCursor.getString(nameCursor.getColumnIndex(
                    ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
            middleName = nameCursor.getString(nameCursor.getColumnIndex(
                    ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME));
            lastName = nameCursor.getString(nameCursor.getColumnIndex(
                    ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
            displayName = nameCursor.getString(nameCursor.getColumnIndex(
                    ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));
        }
然后我将所有这些数据(包括联系人的电子邮件地址和电话号码)发送到服务器

我希望能够像这样定期备份设备的联系人,但是能够通过比较旧数据和新数据来检测联系人数据的变化。但要做到这一点,我需要在android设备中的联系人和我保存联系人数据的数据库之间建立某种链接

经过一番搜索,我找到了3个选项:

ContactsContract.Contacts._ID
ContactsContract.Contacts.LOOKUP_KEY
ContactsContract.RawContacts._ID
但从我发现的情况来看,它们都不可靠,在某些情况下可能会发生变化——使我的数据库与设备联系人列表之间的链接失效

我已经考虑过使用
ContentObserver
检测联系人更改的选项。但是,我希望能够检测到联系人的变化,即使我的应用程序已被卸载,然后一些联系人已更改,然后我的应用程序已重新安装

我是否可以使用每个联系人的可靠识别码来了解某个联系人何时被更改或删除?

编辑:

我现在发现这个变量存在:
ContactsContract.ContactsColumns.CONTACT\u LAST\u UPDATED\u TIMESTAMP


问题是它只在API级别18中引入。我正在研究min API 15。是否有什么东西可以替代缺失的API级别?

恐怕无法知道特定联系人是否发生了变化。因此,您可以在整个地址簿URI上注册观察者。这样,当通讯簿中的任何内容发生变化时,您都可以收听

现在有了observer,您可以扫描所有联系人并将数据“同步”到服务器

在您的特殊情况下,Contacts Contacts.Contacts.\u ID和Contacts Contacts.Contacts.LOOKUP\u密钥应该足够可靠。但为了了解是否有任何变化,您需要:

  • 将所有联系人发送到服务器并在服务器上执行同步逻辑(id和查找密钥应存储在MySQL上)
  • 在设备上保留联系人的本地副本(sqllite db、realm、任何其他存储),以避免每次同步时将未更改的联系人发送到服务器

恐怕无法知道特定联系人是否发生了变化。因此,您可以在整个地址簿URI上注册观察者。这样,当通讯簿中的任何内容发生变化时,您都可以收听

现在有了observer,您可以扫描所有联系人并将数据“同步”到服务器

在您的特殊情况下,Contacts Contacts.Contacts.\u ID和Contacts Contacts.Contacts.LOOKUP\u密钥应该足够可靠。但为了了解是否有任何变化,您需要:

  • 将所有联系人发送到服务器并在服务器上执行同步逻辑(id和查找密钥应存储在MySQL上)
  • 在设备上保留联系人的本地副本(sqllite db、realm、任何其他存储),以避免每次同步时将未更改的联系人发送到服务器

感谢您的回复,我编辑了我的问题-了解了关于contacts contract.contacts columns.CONTACT\u LAST\u UPDATED\u TIMESTAMP的信息。如果我按照您描述的方式实现它,您将如何在服务器端检查ID和查找键?我的意思是,如果只有一个匹配就足够了,或者一个新联系人可能会获得与过去联系人相同的ID或查找键吗?如果联系人的ID+查找键发生变化,那么它可能不会与其他联系人相同。因此,如果您修改联系人,它的查找键可能会更改,因此基本上您是在创建新联系人,必须删除旧联系人谢谢您的答复,我编辑了我的问题-了解了关于contacts contract.contacts columns.contact\u LAST\u UPDATED\u TIMESTAMP的信息。如果我按照您描述的方式实现它,您将如何在服务器端检查ID和查找键?我的意思是,如果只有一个匹配就足够了,或者一个新联系人可能会获得与过去联系人相同的ID或查找键吗?如果联系人的ID+查找键发生变化,那么它可能不会与其他联系人相同。因此,如果您修改联系人,它的查找键很可能会更改,所以基本上您是在创建新联系人,必须删除旧联系人