2017-01-15 93 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來檢測聯繫人更改的選項。但是,即使我的應用程序已被卸載,我希望能夠檢測到聯繫人更改,然後某些聯繫人已更改,然後重新安裝了我的應用程序。

每個聯繫人都有可靠的識別碼,可以用來了解某個聯繫人何時發生了更改或刪除?

編輯:

我現在發現這個變量存在:ContactsContract.ContactsColumns.CONTACT_LAST_UPDATED_TIMESTAMP

的問題是,它是隻介紹API等級18,我在分鐘API 15.工作有什麼可以取代它爲缺少的API級別?

回答

2

恐怕不可能知道特定的接觸是否發生了變化。因此,您可以在整個地址簿URI上註冊觀察員。這樣,當地址簿中的任何內容發生變化時,您都可以收聽。

現在有觀察者可以掃描所有聯繫人並執行「同步」數據到您的服務器。

在您的特定情況下,ContactsContract.Contacts._ID和ContactsContract.Contacts.LOOKUP_KEY對應該足夠可靠。但爲了知道如果有什麼改變了你需要或者:

  • 發送所有聯繫人到服務器,並在服務器上執行同步邏輯(ID和查找鍵應存儲在MySQL的)
  • 保持接觸的本地副本在你設備以避免接觸不變(sqllite分貝,境界,任何其他存儲)將每次同步
+0

謝謝您的回覆時間發送到服務器,我編輯我的問題 - 發現了ContactsContract.ContactsColumns.CONTACT_LAST_UPDATED_TIMESTAMP 。 如果我以你描述的方式實現它,你將如何去檢查服務器端的ID和LOOKUP KEY?我的意思是,如果只有一個匹配,就足夠了,還是有可能新聯繫人在過去會得到與聯繫人相同的ID或LOOKUP KEY? –

+0

如果聯繫人的ID + LOOKUP KEY更改,它不可能與其他聯繫人相同。因此,如果您修改了聯繫方式,可能需要更改其LOOKUP KEY,因此基本上您正在創建新聯繫人,並且必須刪除舊聯繫人 –

相關問題