API Guides Contacts Provider
Contacts Provider? ? ?
Contacts Provider是Android的一個強大組件,它管理聯系人的核心數據。你在手機聯系人看到聯系人信息,來源于Contact Provider。當然,你可以在自己的應用用訪問ContactProvider的數據,也可以同步手機和服務器的的聯系人數據。Contact Provider存儲很多類型的數據,而且為每個聯系人盡可能多的保存數據,因此,它的結構很復雜。Contact Provider的API包含很多擴展的合約(contract class)類和接口,用來方便數據的查找和修改。
這篇向導描述了以下幾點:
1、Contact Provider的基本結構
2、如何從Contact Provider查找數據
3、如何修改Contact Provider的數據
4、如何寫一個sync Adapter用來同步服務器和Contact Provider的數據
這篇向導假設你已經了解Android content provider。要學習更多關于Android content provider的知識,請參考Content Provider Basics 向導.。Sample Sync Adapter是一個使用sync Adapter來同步數據的例子和一個使用Google Web Service的例子。
Contacts Provider Organization
Contact Provider是一個Android的 content provider 組件。關于一個聯系人,它存儲三種類型的數據,每種類型的數據對應一個provider的數據表,如圖1所示:
圖 1. Contacts Provider數據表結構.
這三個表在他們的合約(contract class)類中有描述。這些合約類定義了URI常量,數據表的列名,列的數據類型。三個合約類如下:
ContactsContract.Contacts?:
? ? 每一行代表一個聯系人,基于一行或多行raw contact合并而來的。
ContactsContract.RawContacts?:每一行代表一個聯系人某個特定賬戶的數據摘要。一個聯系人可能會有多個賬戶。 ContactsContract.Data?:每一行代表一個raw contact的詳細數據,例如郵件地址或電話號碼。ContactContract里面定義的其他數據表是一些輔助的數據表,是Contacts Provider 用來管理數據操作或作為聯系人的特別功能或撥打電話程序需要用到。
Raw contacts
一條raw contacts代表聯系人特定賬戶的一條數據。因為Contacts Provider允許多個服務來存儲數據,所以Contacts Providery允許一個聯系人存儲存儲多條raw contacts數據。用戶也可以在相同的賬戶類型中的兩個不同賬戶合并數據。
raw contacts的詳細數據不不是存在表ContactsContract.RawContacts?中的,而是以一行或多行的形式,存儲在表ContactsContract.Data中。Data的每一條數據都有一列Data.RAW_CONTACT_ID,它的值就是指向ContactsContract.RawContacts。
Important raw contact columns(raw contact的重要的列 )
?ContactsContract.RawContacts的重要列在表1中列出。請看表中的說明。
| 列名 | 用途 | 注 |
| ACCOUNT_NAME | 一個賬戶包含賬戶類型和賬戶名,他們作為一條raw contac t的數據源。例如,一個Google賬戶的賬戶名是一個gmail的 郵箱地址。下一行ACCOUNT_TYPE?有更多的說明 | 賬號名的格式和賬號類型相關,不一定是一個郵箱地址 |
| ACCOUNT_TYPE | 賬號類型代表raw contact的數據源。例如,一個谷歌賬戶的 賬戶類型是com.google。通常的賬戶類型是你的域名或者你 掌管的域名 | 一個提供聯系人數據的賬戶類型,通常會有一個sysc? adapter用來同步Contacts Provider的數據。 |
| DELETED | 用來標記一條raw contact是否被刪除 | 由于和服務器的同步不一定是馬上進行,所以需要一個 標記為來標記。等到sync Adapter刪除服務器上的數據 后,就會刪除Contacts provider里面的數據。 |
Notes
一下是ContactsContract.RawContacts表的注意事項:
1、raw contact的名字并不是存在ContactsContract.RawContacts,而是存在ContactsContract.Data中,以一條ContactsContract.CommonDataKinds.StructuredName(里面定義了display name,given name等數據)的數據存儲。在ContactsContract.Data中,每個raw contact只有一條ContactsContract.CommonDataKinds.StructuredName的數據。
2、警告:如果在raw contact中,要保存自己的賬戶類型,必須先在AccountManager中注冊。為此,要提示用戶去添加賬戶類型和賬戶名到賬戶列表中。如果沒有這樣做,Contacts Provider會自動刪除你的raw contact數據。
例如,
你要保存聯系人的數據到你的服務器上,你的服務器的域名是?com.example.dataservice,你有一個用戶名為becky.sharp@dataservice.example.com的賬戶。在你欠佳raw contact數據之前,你必須先添加用戶類型(com.example.dataservice) 和用戶名(becky.smart@dataservice.example.com) 。你可以在用戶手冊中說明這個需求,或者,你可以在應用中提示用戶去添加賬戶類型和賬戶名。或者兩種方式都做。賬戶類型和賬戶名在下面的章節有更詳細的描述。
Sources of raw contacts data
要了解raw contacts是如何工作的,請看例子:用戶Emily Dickinson在她的設備上有三個賬戶:
- emily.dickinson@gmail.com
- emilyd@gmail.com
- Twitter account "belle_of_amherst"
在賬戶設置里面,用戶已經開啟聯系人同步的功能。
假設Emily Dickinson打開一個瀏覽器窗口,登入emily.dickinson@gmail.com的gmail賬戶,打開聯系人,添加聯系人Thomas Higginson。然后,她登入另一個gmail賬戶,即emilyd@gmail.com,發送郵件給Thomas Higginson。她的emilyd@gmail.com自動把Thomas Higginson加為聯系人了。同時,colonel_tom(Thomas Higginson的twitter ID)也在她的Twitter聯系人上了。
在上面的流程中,Contacts Provider創建三條raw contacts。
1、Thomas Higginson的一條賬戶名為emily.dickinson@gmail.com賬戶類型為google的記錄。
2、Thomas Higginson的另一條賬戶名為emilyd@gmail.com,賬戶類型也是Google的記錄。雖然兩條記錄的顯示名字相同,但是它們在raw contact中是兩條記錄,因為它們的賬戶名不同。
3.Thomas Higginson的一條和Twitter賬號belle_of_amherst相關聯的記錄。
Data
正如前面所說的,raw contact的詳細數據存儲在?ContactsContract.Data,?ContactsContract.Data有一列只想raw contact的_ID。這樣允許一條raw contact有多個相同類型的數據,例如多個Email或電話號碼。例如賬戶名為emilyd@gmail.com的Thomas Higginson(在raw contact中的一條記錄,賬戶名為emilyd@gmail.com)有一個thigg@gmail.com的家庭郵箱,還有一個thomas.higginson@gmail.com的工作郵箱。contacts provider存儲這兩條數據,并把他們關聯到同一條raw contact。
不同類型的數據都存儲在這個表中。顯示名,電話號碼,郵件,郵政編碼,圖片和個人主頁等詳細詳細都在?ContactsContract.Data表中。為了便于管理這些數據,?ContactsContract.Data表中,有一些列是描述性名字(descriptive names)的,另一些列是通用名字(generic names)。描述性名字不管存儲的是任何任性的數據,都有相同的意思。而通用名字會根據存儲數據類型的不同,而有不同的意思。
Descriptive column names(描述型的列名)
一些描述型的列名如下:
RAW_CONTACT_ID:指向raw contact的_ID。
MIMETYPE:這一行數據的類型,用一個MIME類型來描述。Contract Provider用的MIME類型,在ContactsContract.CommonDataKinds的子類中描述。這些MIME類型是開放的,可以用在任何應用或Contacts Provider的sync Adapter中。
IS_PRIMARY:如果一條raw contact可以有多條這種類型的數據,IS_PRIMARY標記是否為這種類型數據的關鍵數據。例如,用戶長按一個電話號碼,并設置為默認號碼,那么?ContactsContract.Data?的記錄中,包含這個電話那么的那條數據的IS_PRIMARY?被設為一個非0的值。
Generic column names(通用型列名)
總共有列名為DATA1--DATA15的15列通用型列名,還有用于sync adapter的SYNC1--SYNC4的通用型列名。不管存儲何種數據類型,通用型列名的常量都能用上,即能代表不同類型的數據。
列DATA1有創建索引(用于加快查找)。Contacts Provider用這一列來存儲經常查詢的數據。例如,一條Email的數據中,這一列用來存儲郵件地址。另外,DATA15用來存儲二進制打數據(BLOB),例如圖片縮略圖。
Type-specific column names(定制的列名)
為了便于處理特定數據類型,Contacts Provider提供了一些定制的列名常量,在ContactsContract.CommonDataKinds的子類中定義。這些常量值是用一個不同的名字來表示相同的列名,這樣,讓你更容易訪問特定類型的數據。
例如,?ContactsContract.CommonDataKinds.Email?類中,為MIME類型為Email.CONTENT_ITEM_TYPE的raw contract數據定義了一些常量。這些常量包含用來指向郵件地址的ADDRESS常量。ADDRESS的值實際上和DATA1的值是一樣的。定制的名字便于開發者理解列名的含義。
警告:不要添加自定義的數據到?ContactsContract.Data指定的MIME類型中。如果你這樣做,可能會丟失數據或導致provider出現故障。例如,你不能再MIME類型為?Email.CONTENT_ITEM_TYPE的DATA1中,存儲用戶名而不是郵件地址。如果你使用自定義的MIME類型來存儲一行數據,你可以自由的定制你需要的列名。
下圖說明了一條ContactsContract.Data的描述型列名和數據列名,還有定制的列名如何覆蓋通用型的列名。?
Type-specific column name classes(定制列名的類)
下表展示了常用的定制列名的類。
| ContactsContract.CommonDataKinds.StructuredName | 存儲聯系人的名字信息 | 每一條raw contact在Data中只能有一條這種類型的數據 |
| ContactsContract.CommonDataKinds.Photo | 存儲圖片信息 | 每一條raw contact在Data中只能有一條這種類型的數據 |
| ContactsContract.CommonDataKinds.Email | 存儲郵件信息 | 每一條raw contact在Data中可以有多條這種類型的數據 |
| ContactsContract.CommonDataKinds.StructuredPostal | 存儲郵政地址的信息 | 每一條raw contact在Data中可以有多條這種類型的數據 |
| ContactsContract.CommonDataKinds.GroupMembership | 把raw data關聯到某個組中 | 組是可選的信息,在?Contact groups中有更詳細的描述? ? ? |
Contacts
Contacts Provider把各種不同賬戶名和賬戶類型的raw contact數據組成一個contact表。這樣有助于顯示和修改所有某個聯系人的所有數據。Contacts Provider負責創建新的contact記錄,并把相同聯系人的raw contact記錄聚合在一起。應用程序和sync Adapter都不能添加contact記錄,contact的某些列是只讀的。
注:如果你試圖用insert()方法去插入數據到contact表中,將會拋出UnsupportedOperationException的異常。如果你試圖去更新一個只讀的數據,這個更新的操作將會被忽略。在Contacts Provider中,當新建的raw contact沒有匹配的contact時,就會創建一條新的contact數據。如果已經存在的raw contact數據改變,讓它不在匹配任何contact數據,contacts provider也會為它創建一個新的contact數據。如果應用程序或sync Adapter創建一條raw contact數據,這條新的數據匹配某個已經存在的contact,那么新建的raw contact將被關聯到已經存在的那條contact數據。
Contacts Provider通過Contacts表中的_ID來關聯contact和raw contact。ContactsContract.RawContacts表中的名字為?CONTACT_ID的列,存儲了contacts的_ID。
ContactsContract.Contacts有一個LOOKUP_KEY的列,它存儲一個固定的contact 行號。由于Contacts Provider自動管理contact表,在合并數據或同步的時候,它可能會改變一條數據的_ID。即使_ID改變了,CONTENT_LOOKUP_URI結合LOOKUP_KEY仍然可以指向contact的數據。你可以用?LOOKUP_KEY來保存收藏聯系人等。這一列有它自己的格式,和_ID的格式不相關。
總結
以上是生活随笔為你收集整理的API Guides Contacts Provider的全部內容,希望文章能夠幫你解決所遇到的問題。