2017-01-15 4 views
0

Я создаю приложение для Android, которое отслеживает все контакты, сохраненные на устройстве (те, которые появляются в приложении по умолчанию для Android-приложений) и сохраняет их в таблице MySQL на сервере.Синхронизация контактов android с сервером

мне удалось прочитать все контактные данные, используя 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); 

Затем, используя ContactsContract.Contacts._ID я запрашиваю дополнительные контактные данные:

// 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 для обнаружения изменений контактов. Но я хочу иметь возможность обнаруживать изменения контактов, даже если мое приложение было удалено, затем некоторые контакты изменились, а затем мое приложение было переустановлено.

Есть ли надежный идентификационный ключ для каждого контакта, который я могу использовать, чтобы узнать, когда определенный контакт был изменен или удален?

EDIT:

теперь я нашел эта переменная существует: ContactsContract.ContactsColumns.CONTACT_LAST_UPDATED_TIMESTAMP

Проблема заключается в том, что это только вводит в уровне API 18. Я работаю на мин API 15. Есть ли что-то, что может заменить это за недостающие уровни API?

ответ

2

Я боюсь, что невозможно узнать, изменился ли конкретный контакт. Поэтому вы можете зарегистрировать наблюдателя на URI общей адресной книги. Таким образом, вы сможете слушать, когда что-либо меняется в адресной книге.

Теперь, имея наблюдателя, вы можете сканировать все контакты и выполнять «синхронизацию» данных с вашим сервером.

В вашем конкретном случае пара контактовContract.Contacts._ID и ContactsContract.Contacts.LOOKUP_KEY должна быть достаточно надежной. Но для того, чтобы знать, если что-то изменилось вам нужно либо:

  • посыла все контакты с сервера и выполнять синхронизацию логики на сервере (идентификатор и ключ поиска должен храниться на MySQL)
  • сохранить локальную копию контактов на вашем устройство (sqllite дБ, область, любое другое запоминающее устройство), чтобы избежать изменившихся контактов для отправки на сервер каждый раз, когда вы синхронизацию
+0

Спасибо за ваш ответ, я отредактировал мой вопрос - узнали о ContactsContract.ContactsColumns.CONTACT_LAST_UPDATED_TIMESTAMP , В случае, если я реализую его так, как вы описываете, как бы вы могли проверить идентификатор и LOOKUP KEY на стороне сервера? Я имею в виду, достаточно ли одного, если только один соответствует, или возможно, что новый контакт получит тот же ID или LOOKUP KEY в качестве контакта в прошлом? –

+0

Если ID + LOOKUP KEY изменения контакта, это вряд ли будет таким же, как и для другого контакта. Поэтому, если вы изменяете контакт, вероятно, его ключ LOOKUP KEY будет изменен, поэтому в основном вы создаете новый контакт, а старый должен быть удален –

Смежные вопросы