• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Trình cung cấp Danh bạ
2@jd:body
3<div id="qv-wrapper">
4<div id="qv">
5<h2>Xem nhanh</h2>
6<ul>
7    <li>Kho lưu giữ thông tin về con người của Android.</li>
8    <li>
9        Đồng bộ với web.
10    </li>
11    <li>
12        Tích hợp dữ liệu theo luồng xã hội.
13    </li>
14</ul>
15<h2>Trong tài liệu này</h2>
16<ol>
17    <li>
18        <a href="#InformationTypes">Tổ chức Trình cung cấp Danh bạ</a>
19    </li>
20    <li>
21        <a href="#RawContactBasics">Liên lạc thô</a>
22    </li>
23    <li>
24        <a href="#DataBasics">Dữ liệu</a>
25    </li>
26    <li>
27        <a href="#ContactBasics">Danh bạ</a>
28    </li>
29    <li>
30        <a href="#Sources">Dữ liệu từ Trình điều hợp Đồng bộ</a>
31    </li>
32    <li>
33        <a href="#Permissions">Quyền được Yêu cầu</a>
34    </li>
35    <li>
36        <a href="#UserProfile">Hồ sơ Người dùng</a>
37    </li>
38    <li>
39        <a href="#ContactsProviderMetadata">Siêu dữ liệu Trình cung cấp Danh bạ</a>
40    </li>
41    <li>
42        <a href="#Access">Truy cập Trình cung cấp Danh bạ</a>
43    <li>
44    </li>
45    <li>
46        <a href="#SyncAdapters">Trình điều hợp Đồng bộ Trình cung cấp Danh bạ</a>
47    </li>
48    <li>
49        <a href="#SocialStream">Dữ liệu từ Luồng Xã hội</a>
50    </li>
51    <li>
52        <a href="#AdditionalFeatures">Các Tính năng Bổ sung của Trình cung cấp Danh bạ</a>
53    </li>
54</ol>
55<h2>Lớp khóa</h2>
56<ol>
57    <li>{@link android.provider.ContactsContract.Contacts}</li>
58    <li>{@link android.provider.ContactsContract.RawContacts}</li>
59    <li>{@link android.provider.ContactsContract.Data}</li>
60    <li>{@code android.provider.ContactsContract.StreamItems}</li>
61</ol>
62<h2>Các Mẫu Liên quan</h2>
63<ol>
64    <li>
65        <a href="{@docRoot}resources/samples/ContactManager/index.html">
66        Trình quản lý Danh bạ
67        </a>
68    </li>
69    <li>
70        <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
71        Trình điều hợp Đồng bộ Mẫu</a>
72    </li>
73</ol>
74<h2>Xem thêm</h2>
75<ol>
76    <li>
77        <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
78        Nội dung Cơ bản về Trình cung cấp Nội dung
79        </a>
80    </li>
81</ol>
82</div>
83</div>
84<p>
85    Trình cung cấp Danh bạ là một thành phần Android mạnh mẽ và linh hoạt có chức năng quản lý
86    kho dữ liệu trung tâm về con người của thiết bị. Trình cung cấp Danh bạ là nguồn của những dữ liệu
87    mà bạn thấy trong ứng dụng danh bạ của thiết bị, và bạn cũng có thể truy cập dữ liệu của nó trong
88    ứng dụng của chính mình và chuyển dữ liệu giữa thiết bị và các dịch vụ trực tuyến. Trình cung cấp chứa
89    đủ loại nguồn dữ liệu và cố gắng quản lý nhiều dữ liệu nhất có thể cho mỗi người, kết quả
90    là tổ chức của nó trở nên phức tạp. Vì điều này, API của trình cung cấp bao gồm một
91    tập mở rộng gồm các lớp hợp đồng và giao diện tạo điều kiện cho việc truy xuất và sửa đổi
92    dữ liệu.
93</p>
94<p>
95    Hướng dẫn này trình bày những nội dung sau:
96</p>
97    <ul>
98        <li>
99            Cấu trúc cơ bản của trình cung cấp.
100        </li>
101        <li>
102            Cách truy xuất dữ liệu từ trình cung cấp.
103        </li>
104        <li>
105            Cách sửa đổi dữ liệu trong trình cung cấp.
106        </li>
107        <li>
108            Cách ghi một trình điều hợp đồng bộ để đồng bộ hóa dữ liệu từ máy chủ của bạn với
109            Trình cung cấp Danh bạ.
110        </li>
111    </ul>
112<p>
113    Hướng dẫn này giả sử rằng bạn biết những nội dung cơ bản về trình cung cấp nội dung Android. Để tìm hiểu thêm
114    về trình cung cấp nội dung Android, hãy đọc hướng dẫn
115    <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
116    Nội dung Cơ bản về Trình cung cấp Nội dung</a>. Ứng dụng mẫu
117    <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">Trình điều hợp Đồng bộ Mẫu</a>
118    là một ví dụ về cách sử dụng một trình điều hợp đồng bộ để chuyển dữ liệu giữa Trình cung cấp
119    Danh bạ và ứng dụng mẫu được lưu trữ bởi Dịch vụ Web Google.
120</p>
121<h2 id="InformationTypes">Tổ chức Trình cung cấp Danh bạ</h2>
122<p>
123    Trình cung cấp Danh bạ là một thành phần của trình cung cấp nội dung Android. Nó chứa ba loại
124    dữ liệu về một người, từng loại tương ứng với một bảng do trình cung cấp đưa ra, như
125    được minh họa trong hình 1:
126</p>
127<img src="{@docRoot}images/providers/contacts_structure.png" alt="" height="364" id="figure1" />
128<p class="img-caption">
129  <strong>Hình 1.</strong> Cấu trúc bảng của Trình cung cấp Danh bạ.
130</p>
131<p>
132    Ba bảng này thường được đề cập theo tên các lớp hợp đồng của chúng. Các lớp này
133    sẽ định nghĩa các hằng số cho URI nội dung, tên cột và giá trị cột được sử dụng bởi các bảng:
134</p>
135<dl>
136    <dt>
137        Bảng {@link android.provider.ContactsContract.Contacts}
138    </dt>
139    <dd>
140        Hàng thể hiện những người khác nhau dựa trên tổng hợp của các hàng liên lạc thô.
141    </dd>
142    <dt>
143        Bảng {@link android.provider.ContactsContract.RawContacts}
144    </dt>
145    <dd>
146        Hàng chứa một bản tổng hợp dữ liệu về một người, liên quan tới tài khoản và loại người dùng.
147    </dd>
148    <dt>
149        Bảng {@link android.provider.ContactsContract.Data}
150    </dt>
151    <dd>
152        Hàng chứa các thông tin chi tiết về liên lạc thô, chẳng hạn như địa chỉ e-mail hoặc số điện thoại.
153    </dd>
154</dl>
155<p>
156    Các bảng khác được đại diện bởi các lớp hợp đồng trong {@link android.provider.ContactsContract}
157    là bảng phụ mà Trình cung cấp Danh bạ sử dụng để quản lý thao tác của nó hoặc hỗ trợ
158    các chức năng cụ thể trong ứng dụng danh bạ hoặc điện thoại của thiết bị.
159</p>
160<h2 id="RawContactBasics">Liên lạc thô</h2>
161<p>
162    Một liên lạc thô thể hiện dữ liệu của một người xuất phát từ một loại tài khoản và tên tài khoản
163 riêng. Vì Trình cung cấp Danh bạ cho phép nhiều hơn một dịch vụ trực tuyến làm nguồn
164 dữ liệu cho một người, Trình cung cấp Danh bạ cho phép nhiều liên lạc thô cho cùng một người.
165    Nhiều liên lạc thô cũng cho phép người dùng kết hợp dữ liệu của một người từ nhiều hơn một tài khoản
166 từ cùng loại tài khoản.
167</p>
168<p>
169    Hầu hết dữ liệu của một liên lạc thô không được lưu giữ trong bảng
170    {@link android.provider.ContactsContract.RawContacts}. Thay vào đó, nó được lưu giữ trong một hoặc nhiều
171    hàng trong bảng {@link android.provider.ContactsContract.Data}. Mỗi hàng dữ liệu có một cột
172    {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID Data.RAW_CONTACT_ID} chứa
173    giá trị {@code android.provider.BaseColumns#_ID RawContacts._ID} của
174    hàng {@link android.provider.ContactsContract.RawContacts} mẹ của nó.
175</p>
176<h3 id="RawContactsColumns">Các cột liên lạc thô quan trọng</h3>
177<p>
178    Các cột quan trọng trong bảng {@link android.provider.ContactsContract.RawContacts} được
179    liệt kê trong bảng 1. Hãy đọc các lưu ý theo sau bảng dưới đây:
180</p>
181<p class="table-caption" id="table1">
182    <strong>Bảng 1.</strong> Các cột liên lạc thô quan trọng.
183</p>
184<table>
185    <tr>
186        <th scope="col">Tên cột</th>
187        <th scope="col">Sử dụng</th>
188        <th scope="col">Lưu ý</th>
189    </tr>
190    <tr>
191        <td>
192            {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_NAME}
193        </td>
194        <td>
195            Tên tài khoản cho loại tài khoản là nguồn của liên lạc thô này.
196            Ví dụ, tên tài khoản của một tài khoản Google là một trong các địa chỉ Gmail
197            của chủ sở hữu thiết bị. Xem mục nhập tiếp theo cho
198            {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_TYPE} để biết thêm
199            thông tin.
200        </td>
201        <td>
202            Định dạng của tên này áp dụng theo loại tài khoản của nó. Đó không nhất thiết
203            là một địa chỉ e-mail.
204        </td>
205    </tr>
206    <tr>
207        <td>
208            {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_TYPE}
209        </td>
210        <td>
211            Loại tài khoản là nguồn của liên lạc thô này. Ví dụ, loại tài khoản
212            của một tài khoản Google là <code>com.google</code>. Luôn xác định loại tài khoản của bạn
213            bằng một mã định danh miền cho một miền mà bạn sở hữu hoặc kiểm soát. Điều này đảm bảo rằng loại tài khoản
214            của bạn là duy nhất.
215        </td>
216        <td>
217            Một loại tài khoản cung cấp dữ liệu danh bạ thường có một trình điều hợp đồng bộ liên kết để
218            đồng bộ hoá với Trình điều hợp Đồng bộ.
219    </tr>
220    <tr>
221        <td>
222            {@link android.provider.ContactsContract.RawContactsColumns#DELETED}
223        </td>
224        <td>
225            Cờ "đã xóa" cho một liên lạc thô.
226        </td>
227        <td>
228            Cờ này cho phép Trình cung cấp Danh bạ duy trì hàng bên trong tới khi trình điều hợp đồng bộ
229            có thể xóa hàng đó khỏi máy chủ của chúng rồi cuối cùng là xóa hàng
230            khỏi kho lưu giữ.
231        </td>
232    </tr>
233</table>
234<h4>Lưu ý</h4>
235<p>
236    Sau đây là các ghi chú quan trọng về bảng
237    {@link android.provider.ContactsContract.RawContacts}:
238</p>
239<ul>
240    <li>
241        Tên của liên lạc thô không được lưu giữ trong hàng của nó trong
242        {@link android.provider.ContactsContract.RawContacts}. Thay vào đó, nó được lưu giữ trong
243        bảng {@link android.provider.ContactsContract.Data}, trong một hàng
244        {@link android.provider.ContactsContract.CommonDataKinds.StructuredName}. Liên lạc thô
245        chỉ có một hàng thuộc loại này trong bảng {@link android.provider.ContactsContract.Data}.
246    </li>
247    <li>
248        <strong>Chú ý:</strong> Để sử dụng dữ liệu tài khoản của chính bạn trong một hàng liên lạc thô, trước tiên dữ liệu
249        phải được đăng ký với {@link android.accounts.AccountManager}. Để làm điều này, hãy nhắc
250        người dùng thêm loại tài khoản và tên tài khoản của chúng vào danh sách tài khoản. Nếu bạn không
251        làm vậy, Trình cung cấp Danh bạ sẽ tự động xóa hàng liên lạc thô của bạn.
252        <p>
253            Ví dụ, nếu bạn muốn ứng dụng của mình duy trì dữ liệu danh bạ cho dịch vụ dựa trên nền web của mình
254            với miền {@code com.example.dataservice}, và tài khoản của người dùng cho dịch vụ của bạn
255            là {@code becky.sharp@dataservice.example.com}, trước tiên, người dùng phải thêm
256            "loại" tài khoản ({@code com.example.dataservice}) và "tên" tài khoản
257            ({@code becky.smart@dataservice.example.com}) trước khi ứng dụng của bạn có thể thêm hàng liên lạc thô.
258            Bạn có thể giải thích yêu cầu này với người dùng bằng tài liệu, hoặc bạn có thể nhắc
259            người dùng thêm loại và tên này, hoặc cả hai. Loại tài khoản và tên tài khoản
260            được trình bày chi tiết hơn trong phần sau.
261    </li>
262</ul>
263<h3 id="RawContactsExample">Các nguồn dữ liệu liên lạc thô</h3>
264<p>
265    Để hiểu cách hoạt động của liên lạc thô, hãy xét người dùng "Emily Dickinson", cô ta có ba tài khoản
266    người dùng sau được xác định trên thiết bị của mình:
267</p>
268<ul>
269    <li><code>emily.dickinson@gmail.com</code></li>
270    <li><code>emilyd@gmail.com</code></li>
271    <li>Tài khoản Twitter "belle_of_amherst"</li>
272</ul>
273<p>
274    Người dùng này đã kích hoạt <em>Đồng bộ Danh bạ</em> cho cả ba tài khoản này trong cài đặt
275    <em>Tài khoản</em>.
276</p>
277<p>
278    Giả sử Emily Dickinson mở một cửa sổ trình duyệt, đăng nhập vào Gmail bằng tài khoản
279    <code>emily.dickinson@gmail.com</code>, mở
280    Danh bạ, và thêm "Thomas Higginson". Sau đó, cô đăng nhập vào Gmail bằng tài khoản
281    <code>emilyd@gmail.com</code> và gửi một e-mail tới "Thomas Higginson", làm vậy sẽ tự động
282    thêm người này làm một liên lạc. Cô ấy cũng theo dõi "colonel_tom" (ID Twitter của Thomas Higginson) trên
283    Twitter.
284</p>
285<p>
286    Trình cung cấp Danh bạ sẽ tạo ba liên lạc thô do kết quả của việc làm này:
287</p>
288<ol>
289    <li>
290        Một liên lạc thô cho "Thomas Higginson" liên kết với <code>emily.dickinson@gmail.com</code>.
291        Loại tài khoản người dùng là Google.
292    </li>
293    <li>
294        Một liên lạc thô thứ hai cho "Thomas Higginson" liên kết với <code>emilyd@gmail.com</code>.
295        Loại tài khoản người dùng cũng là Google. Có một liên lạc thô thứ hai ngay cả khi
296        tên giống với một tên trước đó, vì người này đã được thêm cho một
297        tài khoản người dùng khác.
298    </li>
299    <li>
300        Một liên lạc thô thứ ba cho "Thomas Higginson" liên kết với "belle_of_amherst". Loại tài khoản người dùng
301        là Twitter.
302    </li>
303</ol>
304<h2 id="DataBasics">Dữ liệu</h2>
305<p>
306    Như đề cập trước đó, dữ liệu của một liên lạc thô được lưu giữ trong một hàng
307    {@link android.provider.ContactsContract.Data} được liên kết với giá trị
308    <code>_ID</code> của liên lạc thô. Điều này cho phép một liên lạc thô có nhiều thực thể cùng loại
309    dữ liệu chẳng hạn như địa chỉ e-mail hay số điện thoại. Ví dụ, nếu
310    "Thomas Higginson" của {@code emilyd@gmail.com}  (hàng liên lạc thô cho Thomas Higginson
311    liên kết với tài khoản Google <code>emilyd@gmail.com</code>) có một địa chỉ e-mail nhà là
312    <code>thigg@gmail.com</code> và một địa chỉ e-mail cơ quan là
313    <code>thomas.higginson@gmail.com</code>, Trình cung cấp Danh bạ sẽ lưu trữ hai hàng địa chỉ e-mail đó
314    và liên kết cả hai với liên lạc thô.
315</p>
316<p>
317    Để ý rằng các loại dữ liệu khác nhau được lưu giữ trong một bảng này. Các hàng tên hiển thị,
318    số điện thoại, e-mail, địa chỉ gửi thư, ảnh và chi tiết trang web đều được tìm thấy trong bảng
319    {@link android.provider.ContactsContract.Data}. Để giúp quản lý điều này, bảng
320    {@link android.provider.ContactsContract.Data} có một số cột có tên mô tả,
321    và các cột còn lại có tên chung. Các nội dung của cột tên mô tả có cùng ý nghĩa
322    không phụ thuộc vào loại dữ liệu trong hàng, trong khi nội dung của cột tên chung có
323    ý nghĩa khác nhau tùy vào loại dữ liệu.
324</p>
325<h3 id="DescriptiveColumns">Tên cột mô tả</h3>
326<p>
327    Một số ví dụ về tên cột mô tả là:
328</p>
329<dl>
330    <dt>
331        {@link android.provider.ContactsContract.Data#RAW_CONTACT_ID}
332    </dt>
333    <dd>
334        Giá trị của cột <code>_ID</code> của liên lạc thô đối với dữ liệu này.
335    </dd>
336    <dt>
337        {@link android.provider.ContactsContract.Data#MIMETYPE}
338    </dt>
339    <dd>
340        Loại dữ liệu được lưu giữ trong hàng này, được thể hiện dưới dạng một kiểu MIME tùy chỉnh. Trình cung cấp Danh bạ
341        sử dụng các kiểu MIME được định nghĩa trong lớp con của
342        {@link android.provider.ContactsContract.CommonDataKinds}. Các kiểu MIME là nguồn mở,
343        và có thể được sử dụng bởi bất kỳ ứng dụng hay trình điều hợp đồng bộ nào hoạt động với Trình cung cấp Danh bạ.
344    </dd>
345    <dt>
346        {@link android.provider.ContactsContract.DataColumns#IS_PRIMARY}
347    </dt>
348    <dd>
349        Nếu kiểu hàng dữ liệu này có thể xảy ra nhiều hơn một lần đối với một liên lạc thô, cột
350        {@link android.provider.ContactsContract.DataColumns#IS_PRIMARY} sẽ gắn cờ
351        hàng dữ liệu chứa dữ liệu sơ cấp cho kiểu đó. Ví dụ, nếu
352        người dùng nhấn giữ một số điện thoại cho một liên lạc và chọn <strong>Đặt mặc định</strong>,
353        khi đó hàng {@link android.provider.ContactsContract.Data} chứa số đó
354        có cột tương ứng {@link android.provider.ContactsContract.DataColumns#IS_PRIMARY} được đặt thành một
355        giá trị khác 0.
356    </dd>
357</dl>
358<h3 id="GenericColumns">Tên cột chung</h3>
359<p>
360    Có 15 cột chung được đặt tên <code>DATA1</code> thông qua
361    <code>DATA15</code> thường có sẵn và thêm bốn cột
362    chung <code>SYNC1</code> thông qua <code>SYNC4</code> mà chỉ được sử dụng bởi trình điều hợp
363    đồng bộ. Các hằng số tên cột chung luôn có tác dụng, không phụ thuộc vào loại
364    dữ liệu mà hàng đó chứa.
365</p>
366<p>
367    Cột <code>DATA1</code> được đánh chỉ mục.  Trình cung cấp Danh bạ luôn sử dụng cột này cho
368    dữ liệu mà trình cung cấp kỳ vọng sẽ là đối tượng truy vấn thường xuyên nhất. Ví dụ,
369    trong một hàng e-mail, cột này chứa địa chỉ e-mail thực sự.
370</p>
371<p>
372    Theo quy ước, cột <code>DATA15</code> được dành để lưu giữ dữ liệu Binary Large Object
373    (BLOB) chẳng hạn như hình thu nhỏ của ảnh.
374</p>
375<h3 id="TypeSpecificNames">Tên cột theo kiểu</h3>
376<p>
377    Để tạo điều kiện làm việc với các cột đối với một kiểu hàng cụ thể, Trình cung cấp Danh bạ
378    cũng cung cấp các hằng số tên cột theo kiểu, được định nghĩa trong các lớp con của
379    {@link android.provider.ContactsContract.CommonDataKinds}. Các hằng số chỉ cấp một
380    tên hằng số khác cho cùng tên cột, điều này giúp bạn truy cập dữ liệu trong một hàng thuộc
381    một kiểu cụ thể.
382</p>
383<p>
384    Ví dụ, lớp {@link android.provider.ContactsContract.CommonDataKinds.Email} định nghĩa
385    các hằng số tên cột theo kiểu cho một hàng {@link android.provider.ContactsContract.Data} mà
386    có kiểu MIME
387    {@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_ITEM_TYPE
388    Email.CONTENT_ITEM_TYPE}. Lớp chứa hằng số
389    {@link android.provider.ContactsContract.CommonDataKinds.Email#ADDRESS} cho cột
390    địa chỉ e-mail. Giá trị thực sự của
391    {@link android.provider.ContactsContract.CommonDataKinds.Email#ADDRESS} là "data1", giá trị này
392    giống hệt như tên chung của cột.
393</p>
394<p class="caution">
395    <strong>Chú ý:</strong> Không được thêm dữ liệu tùy chỉnh của chính bạn vào bảng
396    {@link android.provider.ContactsContract.Data} bằng cách sử dụng một hàng có một trong các kiểu MIME được xác định trước
397    của trình cung cấp. Nếu làm vậy, bạn có thể làm mất dữ liệu hoặc khiến trình cung cấp
398    gặp trục trặc. Ví dụ, bạn không nên thêm một hàng có kiểu MIME
399    {@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_ITEM_TYPE
400    Email.CONTENT_ITEM_TYPE} mà chứa tên người dùng thay vì địa chỉ e-mail trong cột
401    <code>DATA1</code>. Nếu sử dụng kiểu MIME tùy chỉnh của mình cho hàng, khi đó bạn được tự do
402    định nghĩa tên cột theo kiểu của chính mình và sử dụng các cột theo cách bạn muốn.
403</p>
404<p>
405    Hình 2 minh họa cách các cột mô tả và cột dữ liệu xuất hiện trong hàng
406    {@link android.provider.ContactsContract.Data}, và cách mà tên cột theo kiểu "phủ lên"
407   tên cột chung
408</p>
409<img src="{@docRoot}images/providers/data_columns.png" alt="How type-specific column names map to generic column names" height="311" id="figure2" />
410<p class="img-caption">
411  <strong>Hình 2.</strong> Tên cột theo kiểu và tên cột chung.
412</p>
413<h3 id="ColumnMaps">Lớp tên cột theo kiểu</h3>
414<p>
415    Bảng 2 liệt kê các lớp tên cột theo kiểu thường được sử dụng nhất:
416</p>
417<p class="table-caption" id="table2">
418  <strong>Bảng 2.</strong> Lớp tên cột theo kiểu</p>
419<table>
420  <tr>
421    <th scope="col">Lớp ánh xạ</th>
422    <th scope="col">Kiểu dữ liệu</th>
423    <th scope="col">Lưu ý</th>
424  </tr>
425  <tr>
426    <td>{@link android.provider.ContactsContract.CommonDataKinds.StructuredName}</td>
427    <td>Dữ liệu tên của liên lạc thô liên kết với hàng dữ liệu này.</td>
428    <td>Một liên lạc thô chỉ có một trong những hàng này.</td>
429  </tr>
430  <tr>
431    <td>{@link android.provider.ContactsContract.CommonDataKinds.Photo}</td>
432    <td>Ảnh chính của liên lạc thô được liên kết với hàng dữ liệu này.</td>
433    <td>Một liên lạc thô chỉ có một trong những hàng này.</td>
434  </tr>
435  <tr>
436    <td>{@link android.provider.ContactsContract.CommonDataKinds.Email}</td>
437    <td>Địa chỉ e-mail của liên lạc thô được liên kết với hàng dữ liệu này.</td>
438    <td>Một liên lạc thô có thể có nhiều địa chỉ e-mail.</td>
439  </tr>
440  <tr>
441    <td>{@link android.provider.ContactsContract.CommonDataKinds.StructuredPostal}</td>
442    <td>Địa chỉ cổng của liên lạc thô được liên kết với hàng dữ liệu này.</td>
443    <td>Một liên lạc thô có thể có nhiều địa chỉ cổng.</td>
444  </tr>
445  <tr>
446    <td>{@link android.provider.ContactsContract.CommonDataKinds.GroupMembership}</td>
447    <td>Mã định danh liên kết liên lạc thô với một trong các nhóm trong Trình cung cấp Danh bạ.</td>
448    <td>
449        Nhóm là một tính năng tùy chọn của loại tài khoản và tên tài khoản. Chúng được mô tả
450        chi tiết hơn trong phần <a href="#Groups">Nhóm liên lạc</a>.
451    </td>
452  </tr>
453</table>
454<h3 id="ContactBasics">Danh bạ</h3>
455<p>
456    Trình cung cấp Danh bạ kết hợp các hàng liên lạc thô giữa tất cả các loại tài khoản và tên tài khoản
457    để tạo thành một <strong>liên lạc</strong>. Điều này tạo điều kiện để hiển thị và sửa đổi tất cả dữ liệu mà một
458    người dùng đã thu thập cho một người. Trình cung cấp Danh bạ quản lý việc tạo các hàng liên lạc mới
459    và tổng hợp các liên lạc thô với hàng liên lạc hiện có. Ứng dụng lẫn
460    trình điều hợp đồng bộ đều không được cho phép thêm liên lạc và một số cột trong một hàng liên lạc là cột chỉ đọc.
461</p>
462<p class="note">
463    <strong>Lưu ý:</strong> Nếu bạn cố gắng thêm một liên lạc vào Trình cung cấp Danh bạ có một
464    {@link android.content.ContentResolver#insert(Uri,ContentValues) insert()}, bạn sẽ gặp
465    lỗi ngoại lệ {@link java.lang.UnsupportedOperationException}. Nếu bạn cố gắng cập nhật một cột
466    mà được liệt kê là "chỉ đọc," cập nhật sẽ bị bỏ qua.
467</p>
468<p>
469    Trình cung cấp Danh bạ tạo một liên lạc mới để hồi đáp lại việc thêm một liên lạc thô mới
470    không khớp với bất kỳ liên lạc nào hiện có. Trình cung cấp cũng làm vậy nếu dữ liệu
471    của một liên lạc thô hiện có thay đổi sao cho nó không còn khớp với liên lạc mà trước đó
472    nó được gắn với. Nếu một ứng dụng hoặc trình điều hợp đồng bộ tạo một liên lạc thô mới mà
473    <em>khớp</em> với một liên lạc hiện tại, liên lạc thô mới sẽ được tổng hợp vào liên lạc
474    hiện có.
475</p>
476<p>
477    Trình cung cấp Danh bạ sẽ liên kết một hàng liên lạc với các hàng liên lạc thô của nó bằng cột
478    <code>_ID</code> của hàng liên lạc đó trong bảng {@link android.provider.ContactsContract.Contacts Contacts}
479. Cột <code>CONTACT_ID</code> của bảng liên lạc thô
480    {@link android.provider.ContactsContract.RawContacts} chứa các giá trị <code>_ID</code> cho
481    các hàng liên lạc liên kết với từng hàng liên lạc thô.
482</p>
483<p>
484    Bảng {@link android.provider.ContactsContract.Contacts} cũng có cột
485    {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} mà là một liên kết
486    "cố định" với hàng liên lạc đó. Vì Trình cung cấp Danh bạ tự động duy trì
487    các liên lạc, nó có thể thay đổi giá trị {@code android.provider.BaseColumns#_ID} của một hàng liên lạc
488    hồi đáp lại một sự tổng hợp hoặc đồng bộ. Ngay cả khi điều này xảy ra, URI nội dung
489    {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI} kết hợp với
490    {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} của liên lạc sẽ vẫn
491    chỉ về hàng liên lạc đó, vì thế bạn có thể sử dụng
492    {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY}
493    để duy trì các liên kết đến liên lạc "yêu thích", v.v. Cột này có định dạng riêng không
494    liên quan tới định dạng của cột {@code android.provider.BaseColumns#_ID}.
495</p>
496<p>
497    Hình 3 minh họa mối liên quan giữa ba bảng chính này với nhau.
498</p>
499<img src="{@docRoot}images/providers/contacts_tables.png" alt="Contacts provider main tables" height="514" id="figure4" />
500<p class="img-caption">
501  <strong>Hình 3.</strong> Mối quan hệ giữa các bảng Danh bạ, Liên lạc Thô, và Chi tiết.
502</p>
503<h2 id="Sources">Dữ liệu từ Trình điều hợp Đồng bộ</h2>
504<p>
505    Người dùng nhập dữ liệu danh bạ trực tiếp vào thiết bị, nhưng dữ liệu cũng đi đến Trình cung cấp
506    Danh bạ từ các dịch vụ web thông qua <strong>trình điều hợp đồng bộ</strong>, giúp tự động
507    chuyển dữ liệu giữa thiết bị và các dịch vụ. Trình điều hợp đồng bộ chạy ngầm
508    dưới sự kiểm soát của hệ thống, và chúng gọi các phương pháp {@link android.content.ContentResolver} để
509    quản lý dữ liệu.
510</p>
511<p>
512    Trong Android, dịch vụ web mà một trình điều hợp đồng bộ làm việc cùng sẽ được xác định bằng một loại tài khoản.
513    Mỗi trình điều hợp đồng bộ làm việc với một loại tài khoản, nhưng nó có thể hỗ trợ nhiều tên tài khoản cho
514    loại đó. Các loại tài khoản và tên tài khoản được mô tả sơ qua trong phần
515    <a href="#RawContactsExample">Các nguồn dữ liệu liên lạc thô</a>. Các định nghĩa sau trình bày
516    chi tiết hơn và mô tả mối liên quan giữa loại và tên tài khoản với các trình điều hợp đồng bộ và dịch vụ.
517</p>
518<dl>
519    <dt>
520        Loại tài khoản
521    </dt>
522    <dd>
523        Xác định một dịch vụ mà người dùng đã lưu giữ dữ liệu trong đó. Trong phần lớn thời gian, người dùng phải
524        xác thực dịch vụ. Ví dụ, Google Contacts là một loại tài khoản được xác định
525        bởi mã <code>google.com</code>. Giá trị này tương ứng với loại tài khoản được sử dụng bởi
526        {@link android.accounts.AccountManager}.
527    </dd>
528    <dt>
529        Tên tài khoản
530    </dt>
531    <dd>
532        Xác định một tài khoản hoặc đăng nhập cụ thể cho một loại tài khoản. Tài khoản Google Contacts
533        giống như tài khoản Google, chúng có một địa chỉ e-mail làm tên tài khoản.
534        Các dịch vụ khác có thể sử dụng tên người dùng là một từ hoặc id chữ số.
535    </dd>
536</dl>
537<p>
538    Loại tài khoản không nhất thiết phải duy nhất. Một người dùng có thể cấu hình nhiều tài khoản Google Contacts
539    và tải xuống dữ liệu của chúng vào Trình cung cấp Danh bạ; điều này có thể xảy ra nếu người dùng có một tập hợp
540    các liên lạc cá nhân cho một tên tài khoản cá nhân, và một tập hợp khác cho cơ quan. Tên tài khoản thường
541    là duy nhất. Cùng nhau, chúng xác định một dòng dữ liệu cụ thể giữa Trình cung cấp Danh bạ và
542    một dịch vụ bên ngoài.
543</p>
544<p>
545    Nếu muốn chuyển dữ liệu từ dịch vụ của bạn sang Trình cung cấp Danh bạ, bạn cần ghi
546    vào trình điều hợp đồng bộ của chính mình. Điều này được mô tả chi tiết hơn trong phần
547    <a href="#SyncAdapters">Trình điều hợp Đồng bộ Trình cung cấp Danh bạ</a>.
548</p>
549<p>
550    Hình 4 minh họa cách mà Trình cung cấp Danh bạ phù hợp với dòng dữ liệu
551    về con người. Trong hộp được đánh dấu "trình điều hợp đồng bộ," mỗi trình điều hợp được ghi nhãn theo loại tài khoản của nó.
552</p>
553<img src="{@docRoot}images/providers/ContactsDataFlow.png" alt="Flow of data about people" height="252" id="figure5" />
554<p class="img-caption">
555  <strong>Hình 4.</strong> Luồng dữ liệu của Trình cung cấp Danh bạ.
556</p>
557<h2 id="Permissions">Quyền được Yêu cầu</h2>
558<p>
559    Những ứng dụng muốn truy cập Trình cung cấp Danh bạ phải yêu cầu các quyền
560    sau:
561</p>
562<dl>
563    <dt>Quyền truy cập đọc vào một hoặc nhiều bảng</dt>
564    <dd>
565        {@link android.Manifest.permission#READ_CONTACTS}, được quy định trong
566        <code>AndroidManifest.xml</code> với phần tử
567        <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">
568        &lt;uses-permission&gt;</a></code> là
569        <code>&lt;uses-permission android:name="android.permission.READ_CONTACTS"&gt;</code>.
570    </dd>
571    <dt>Quyền truy cập ghi vào một hoặc nhiều bảng</dt>
572    <dd>
573        {@link android.Manifest.permission#WRITE_CONTACTS}, được quy định trong
574        <code>AndroidManifest.xml</code> với phần tử
575        <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">
576        &lt;uses-permission&gt;</a></code> là
577        <code>&lt;uses-permission android:name="android.permission.WRITE_CONTACTS"&gt;</code>.
578    </dd>
579</dl>
580<p>
581    Những quyền này không mở rộng sang dữ liệu hồ sơ người dùng. Hồ sơ người dùng và các quyền
582    được yêu cầu được đề cập trong phần sau,
583    <a href="#UserProfile">Hồ sơ Người dùng</a>.
584</p>
585<p>
586    Nhớ rằng dữ liệu danh bạ của người dùng là dữ liệu cá nhân và nhạy cảm. Người dùng quan tâm về
587    quyền riêng tư của họ, vì thế họ không muốn các ứng dụng thu thập dữ liệu về mình hoặc danh bạ của mình.
588    Nếu không rõ ràng về lý do bạn cần quyền truy cập dữ liệu danh bạ của họ, họ có thể cho
589    ứng dụng của bạn đánh giá thấp hoặc từ chối cài đặt ứng dụng.
590</p>
591<h2 id="UserProfile">Hồ sơ Người dùng</h2>
592<p>
593    Bảng {@link android.provider.ContactsContract.Contacts} có một hàng đơn chứa
594    dữ liệu hồ sơ cho người dùng của thiết bị. Dữ liệu này mô tả <code>user</code> của thiết bị chứ không phải
595    của một trong các liên lạc của người dùng. Hàng liên lạc hồ sơ được liên kết với hàng
596    liên lạc thô đối với từng hệ thống sử dụng hồ sơ.
597    Mỗi hàng liên lạc thô của hồ sơ có thể có nhiều hàng dữ liệu. Các hằng số để truy cập hồ sơ
598    người dùng có sẵn trong lớp {@link android.provider.ContactsContract.Profile}.
599</p>
600<p>
601    Truy cập hồ sơ người dùng đòi hỏi phải có các quyền đặc biệt. Ngoài các quyền
602    {@link android.Manifest.permission#READ_CONTACTS} và
603    {@link android.Manifest.permission#WRITE_CONTACTS} cần để đọc và ghi, truy cập
604    hồ sơ người dùng còn yêu cầu quyền {@code android.Manifest.permission#READ_PROFILE} và
605    {@code android.Manifest.permission#WRITE_PROFILE} tương ứng cho quyền truy cập đọc và
606    ghi.
607</p>
608<p>
609    Nhớ rằng bạn nên coi hồ sơ của một người dùng là nội dung nhạy cảm. Quyền
610    {@code android.Manifest.permission#READ_PROFILE} cho phép bạn truy cập dữ liệu xác định cá nhân
611    của người dùng thiết bị. Chắc chắn phải nói cho người dùng biết lý do tại sao
612    bạn cần các quyền truy cập hồ sơ người dùng trong phần mô tả ứng dụng của mình.
613</p>
614<p>
615    Để truy xuất hàng liên lạc chứa hồ sơ của người dùng,
616    hãy gọi {@link android.content.ContentResolver#query(Uri,String[], String, String[], String)
617    ContentResolver.query()}. Đặt URI nội dung thành
618    {@link android.provider.ContactsContract.Profile#CONTENT_URI} và không cung cấp bất kỳ
619    tiêu chí lựa chọn nào. Bạn cũng có thể sử dụng URI nội dung này làm URI cơ sở để truy xuất các liên lạc thô
620    hoặc dữ liệu cho hồ sơ. Ví dụ, đoạn mã HTML này truy xuất dữ liệu cho hồ sơ:
621</p>
622<pre>
623// Sets the columns to retrieve for the user profile
624mProjection = new String[]
625    {
626        Profile._ID,
627        Profile.DISPLAY_NAME_PRIMARY,
628        Profile.LOOKUP_KEY,
629        Profile.PHOTO_THUMBNAIL_URI
630    };
631
632// Retrieves the profile from the Contacts Provider
633mProfileCursor =
634        getContentResolver().query(
635                Profile.CONTENT_URI,
636                mProjection ,
637                null,
638                null,
639                null);
640</pre>
641<p class="note">
642    <strong>Lưu ý:</strong> Nếu bạn truy xuất nhiều hàng liên lạc và muốn xác định xem một trong số chúng có phải
643    là hồ sơ người dùng không, hãy kiểm tra cột
644    {@link android.provider.ContactsContract.ContactsColumns#IS_USER_PROFILE} của hàng. Cột này
645    được đặt thành "1" nếu liên lạc là hồ sơ người dùng.
646</p>
647<h2 id="ContactsProviderMetadata">Siêu dữ liệu Trình cung cấp Danh bạ</h2>
648<p>
649    Trình cung cấp Danh bạ quản lý dữ liệu theo dõi trạng thái của dữ liệu danh bạ trong
650    kho lưu giữ. Siêu dữ liệu về kho lưu giữ này được lưu giữ ở nhiều nơi khác nhau, bao gồm
651    các hàng bảng Liên lạc Thô, Dữ liệu, và Danh bạ, bảng
652    {@link android.provider.ContactsContract.Settings}, và bảng
653    {@link android.provider.ContactsContract.SyncState}. Bảng sau đây cho biết
654    ảnh hưởng của từng mục trong siêu dữ liệu này:
655</p>
656<p class="table-caption" id="table3">
657  <strong>Bảng 3.</strong> Siêu dữ liệu trong Trình cung cấp Danh bạ</p>
658<table>
659    <tr>
660        <th scope="col">Bảng</th>
661        <th scope="col">Cột</th>
662        <th scope="col">Giá trị</th>
663        <th scope="col">Ý nghĩa</th>
664    </tr>
665    <tr>
666        <td rowspan="2">{@link android.provider.ContactsContract.RawContacts}</td>
667        <td rowspan="2">{@link android.provider.ContactsContract.SyncColumns#DIRTY}</td>
668        <td>"0" - không thay đổi kể từ lần đồng bộ cuối cùng.</td>
669        <td rowspan="2">
670            Đánh dấu các liên lạc thô đã được thay đổi trên thiết bị và phải được đồng bộ trở lại
671            máy chủ. Giá trị được đặt tự động bởi Trình cung cấp Danh bạ khi các ứng dụng
672            Android cập nhật một hàng.
673            <p>
674                Các trình điều hợp đồng bộ sửa đổi bảng liên lạc thô hoặc dữ liệu nên luôn nối
675                xâu {@link android.provider.ContactsContract#CALLER_IS_SYNCADAPTER} với
676                URI nội dung mà chúng sử dụng. Làm vậy sẽ ngăn không cho trình cung cấp đánh dấu hàng là không tốt.
677                Nếu không, các sửa đổi trình điều hợp đồng bộ xem như sửa đổi cục bộ và được
678                gửi tới máy chủ, ngay cả khi máy chủ là nguồn sửa đổi.
679            </p>
680        </td>
681    </tr>
682    <tr>
683            <td>"1" - đã thay đổi kể từ lần đồng bộ cuối cùng, cần được đồng bộ lại máy chủ.</td>
684    </tr>
685    <tr>
686        <td>{@link android.provider.ContactsContract.RawContacts}</td>
687        <td>{@link android.provider.ContactsContract.SyncColumns#VERSION}</td>
688        <td>Số phiên bản của hàng này.</td>
689        <td>
690            Trình cung cấp Danh bạ tự động tăng dần giá trị này bất cứ khi nào hàng hoặc
691            dữ liệu có liên quan của hàng thay đổi.
692        </td>
693    </tr>
694    <tr>
695        <td>{@link android.provider.ContactsContract.Data}</td>
696        <td>{@link android.provider.ContactsContract.DataColumns#DATA_VERSION}</td>
697        <td>Số phiên bản của hàng này.</td>
698        <td>
699            Trình cung cấp Danh bạ tự động tăng dần giá trị này bất cứ khi nào hàng dữ liệu
700            bị thay đổi.
701        </td>
702    </tr>
703    <tr>
704        <td>{@link android.provider.ContactsContract.RawContacts}</td>
705        <td>{@link android.provider.ContactsContract.SyncColumns#SOURCE_ID}</td>
706        <td>
707            Một xâu giá trị xác định duy nhất liên lạc thô này cho tài khoản mà
708            nó được tạo trong đó.
709        </td>
710        <td>
711            Khi một trình điều hợp đồng bộ tạo một liên lạc thô mới, cột này nên được đặt thành
712            ID duy nhất của máy chủ dành cho liên lạc thô đó. Khi một ứng dụng Android tạo một liên lạc thô
713            mới, ứng dụng đó sẽ để trống cột này. Điều này báo hiệu với trình điều hợp
714            đồng bộ rằng nó nên tạo một liên lạc thô mới trên máy chủ, và lấy một
715            giá trị cho {@link android.provider.ContactsContract.SyncColumns#SOURCE_ID}.
716            <p>
717                Cụ thể, id nguồn phải là <strong>duy nhất</strong> đối với từng loại tài khoản
718                và nên ổn định giữa các lần đồng bộ:
719            </p>
720                <ul>
721                    <li>
722                        Duy nhất: Mỗi liên lạc thô đối với một tài khoản phải có id nguồn riêng của mình. Nếu không
723                        thi hành điều này, bạn sẽ gây ra sự cố trong ứng dụng danh bạ.
724                        Để ý rằng hai liên lạc thô đối với cùng <em>loại</em> tài khoản có thể có
725                        cùng id nguồn. Ví dụ, liên lạc thô "Thomas Higginson" đối với
726                        tài khoản {@code emily.dickinson@gmail.com} được cho phép có cùng id nguồn
727                        như liên lạc thô "Thomas Higginson" đối với tài khoản
728                        {@code emilyd@gmail.com}.
729                    </li>
730                    <li>
731                        Ổn định: Id nguồn là một bộ phận cố định của dữ liệu từ dịch vụ trực tuyến đối với
732                        liên lạc thô. Ví dụ, nếu người dùng xóa Lưu trữ Danh bạ khỏi
733                        cài đặt Ứng dụng và đồng bộ lại, các liên lạc thô được khôi phục sẽ có cùng
734                        id nguồn như trước. Nếu bạn không thi hành điều này, các lối tắt sẽ dừng
735                        hoạt động.
736                    </li>
737                </ul>
738        </td>
739    </tr>
740    <tr>
741        <td rowspan="2">{@link android.provider.ContactsContract.Groups}</td>
742        <td rowspan="2">{@link android.provider.ContactsContract.GroupsColumns#GROUP_VISIBLE}</td>
743        <td>"0" - Các liên lạc trong nhóm này không nên được hiển thị trong UI ứng dụng Android.</td>
744        <td>
745            Cột này dành cho tính tương thích với các máy chủ mà cho phép người dùng ẩn các liên lạc trong
746            một số nhóm.
747        </td>
748    </tr>
749    <tr>
750        <td>"1" - Các liên lạc trong nhóm này được cho phép hiển thị trong UI ứng dụng.</td>
751    </tr>
752    <tr>
753        <td rowspan="2">{@link android.provider.ContactsContract.Settings}</td>
754        <td rowspan="2">
755            {@link android.provider.ContactsContract.SettingsColumns#UNGROUPED_VISIBLE}</td>
756        <td>
757            "0" - Đối với tài khoản và loại tài khoản này, những liên lạc không thuộc về nhóm
758            được ẩn đối với UI ứng dụng Android.
759        </td>
760        <td rowspan="2">
761            Theo mặc định, các liên lạc được hiển thị nếu không có liên lạc thô nào của chúng thuộc về một nhóm
762            (Tư cách thành viên nhóm đối với một liên lạc thô được thể hiện bằng một hoặc nhiều hàng
763            {@link android.provider.ContactsContract.CommonDataKinds.GroupMembership} trong
764            bảng {@link android.provider.ContactsContract.Data}).
765            Bằng cách đặt cờ này trong hàng bảng {@link android.provider.ContactsContract.Settings} đối với
766            một loại tài khoản và tài khoản, bạn có thể buộc những liên lạc không có nhóm phải hiển thị.
767            Một công dụng của cờ này đó là để hiển thị liên lạc từ các máy chủ không sử dụng nhóm.
768        </td>
769    </tr>
770    <tr>
771        <td>
772            "1" - Đối với tài khoản và loại tài khoản này, những liên lạc không thuộc về nhóm
773            sẽ được hiển thị đối với UI ứng dụng.
774        </td>
775
776    </tr>
777    <tr>
778        <td>{@link android.provider.ContactsContract.SyncState}</td>
779        <td>(tất cả)</td>
780        <td>
781            Sử dụng bảng này để lưu giữ siêu dữ liệu cho trình điều hợp đồng bộ của bạn.
782        </td>
783        <td>
784            Với bảng này, bạn có thể lưu giữ trạng thái đồng bộ và các dữ liệu khác liên quan tới đồng bộ một cách lâu dài
785            trên thiết bị.
786        </td>
787    </tr>
788</table>
789<h2 id="Access">Truy cập Trình cung cấp Danh bạ</h2>
790<p>
791    Phần này mô tả các hướng dẫn về truy cập dữ liệu từ Trình cung cấp Danh bạ, tập trung vào những
792    nội dung sau:
793</p>
794<ul>
795    <li>
796        Truy vấn thực thể.
797    </li>
798    <li>
799        Sửa đổi hàng loạt.
800    </li>
801    <li>
802        Truy xuất và sửa đổi bằng ý định.
803    </li>
804    <li>
805        Toàn vẹn dữ liệu.
806    </li>
807</ul>
808<p>
809    Thực hiện sửa đổi từ một trình điều hợp đồng bộ cũng được đề cập chi tiết hơn trong phần
810    <a href="#SyncAdapters">Trình điều hợp Đồng bộ Trình cung cấp Danh bạ</a>.
811</p>
812<h3 id="Entities">Truy vấn thực thể</h3>
813<p>
814    Vì các bảng của Trình cung cấp Danh bạ được tổ chức theo một phân cấp, thường sẽ hữu ích nếu
815    truy xuất một hàng và tất cả hàng "con" được liên kết với nó. Ví dụ, để hiển thị
816    tất cả thông tin cho một người, bạn có thể muốn truy xuất tất cả hàng
817    {@link android.provider.ContactsContract.RawContacts} đối với một hàng
818    {@link android.provider.ContactsContract.Contacts} đơn, hoặc tất cả hàng
819    {@link android.provider.ContactsContract.CommonDataKinds.Email} đối với một hàng
820    {@link android.provider.ContactsContract.RawContacts} đơn. Để tạo điều kiện cho điều này, Trình cung cấp
821    Danh bạ sẽ cung cấp các cấu trúc <strong>thực thể</strong> đóng vai trò như liên kết cơ sở dữ liệu
822    giữa các bảng.
823</p>
824<p>
825    Thực thể giống như một bảng bao gồm các cột được chọn từ một bảng mẹ và bảng con của nó.
826    Khi bạn truy vấn một thực thể, bạn cung cấp một dự thảo và các tiêu chí dựa trên các cột
827    có sẵn từ thực thể. Kết quả là một {@link android.database.Cursor} trong đó chứa
828    một hàng cho từng hàng bảng con được truy xuất. Ví dụ, nếu bạn truy vấn
829    {@link android.provider.ContactsContract.Contacts.Entity} cho một tên liên lạc
830    và tất cả hàng {@link android.provider.ContactsContract.CommonDataKinds.Email} đối với tất cả
831    liên lạc thô cho tên đó, bạn sẽ nhận lại một {@link android.database.Cursor} chứa một hàng
832    cho mỗi hàng {@link android.provider.ContactsContract.CommonDataKinds.Email}.
833</p>
834<p>
835    Các thực thể sẽ đơn giản hóa việc truy vấn. Bằng cách sử dụng một thực thể, bạn có thể truy xuất ngay lập tức tất cả dữ liệu danh bạ cho một
836    liên lạc hoặc liên lạc thô, thay vì phải truy vấn bảng mẹ trước để nhận một
837    ID, và rồi phải truy xuất bảng con bằng ID đó. Đồng thời, Trình cung cấp Danh bạ xử lý
838    một truy vấn đối với một thực thể trong một giao tác đơn, điều này đảm bảo rằng dữ liệu được truy xuất sẽ được
839    nhất quán trong nội bộ.
840</p>
841<p class="note">
842    <strong>Lưu ý:</strong> Một thực thể thường không chứa tất cả cột của bảng mẹ và
843    bảng con. Nếu bạn cố gắng làm việc với một tên cột không có trong danh sách các hằng số tên cột
844    đối với thực thể đó, bạn sẽ nhận được một {@link java.lang.Exception}.
845</p>
846<p>
847    Đoạn mã HTML sau cho biết cách truy xuất tất cả hàng liên lạc thô cho một liên lạc. Đoạn mã HTML
848    là bộ phận của một ứng dụng lớn hơn có hai hoạt động, "chính" và "chi tiết". Hoạt động chính
849    hiển thị một danh sách các hàng liên lạc; khi người dùng chọn một hàng, hoạt động sẽ gửi ID của hàng tới hoạt động
850    chi tiết. Hoạt động chi tiết sử dụng {@link android.provider.ContactsContract.Contacts.Entity}
851    để hiển thị tất cả hàng dữ liệu từ tất cả liên lạc thô được liên kết với liên lạc
852    đã chọn.
853</p>
854<p>
855    Đoạn mã HTML này được lấy từ hoạt động "chi tiết":
856</p>
857<pre>
858...
859    /*
860     * Appends the entity path to the URI. In the case of the Contacts Provider, the
861     * expected URI is content://com.google.contacts/#/entity (# is the ID value).
862     */
863    mContactUri = Uri.withAppendedPath(
864            mContactUri,
865            ContactsContract.Contacts.Entity.CONTENT_DIRECTORY);
866
867    // Initializes the loader identified by LOADER_ID.
868    getLoaderManager().initLoader(
869            LOADER_ID,  // The identifier of the loader to initialize
870            null,       // Arguments for the loader (in this case, none)
871            this);      // The context of the activity
872
873    // Creates a new cursor adapter to attach to the list view
874    mCursorAdapter = new SimpleCursorAdapter(
875            this,                        // the context of the activity
876            R.layout.detail_list_item,   // the view item containing the detail widgets
877            mCursor,                     // the backing cursor
878            mFromColumns,                // the columns in the cursor that provide the data
879            mToViews,                    // the views in the view item that display the data
880            0);                          // flags
881
882    // Sets the ListView's backing adapter.
883    mRawContactList.setAdapter(mCursorAdapter);
884...
885&#64;Override
886public Loader&lt;Cursor&gt; onCreateLoader(int id, Bundle args) {
887
888    /*
889     * Sets the columns to retrieve.
890     * RAW_CONTACT_ID is included to identify the raw contact associated with the data row.
891     * DATA1 contains the first column in the data row (usually the most important one).
892     * MIMETYPE indicates the type of data in the data row.
893     */
894    String[] projection =
895        {
896            ContactsContract.Contacts.Entity.RAW_CONTACT_ID,
897            ContactsContract.Contacts.Entity.DATA1,
898            ContactsContract.Contacts.Entity.MIMETYPE
899        };
900
901    /*
902     * Sorts the retrieved cursor by raw contact id, to keep all data rows for a single raw
903     * contact collated together.
904     */
905    String sortOrder =
906            ContactsContract.Contacts.Entity.RAW_CONTACT_ID +
907            " ASC";
908
909    /*
910     * Returns a new CursorLoader. The arguments are similar to
911     * ContentResolver.query(), except for the Context argument, which supplies the location of
912     * the ContentResolver to use.
913     */
914    return new CursorLoader(
915            getApplicationContext(),  // The activity's context
916            mContactUri,              // The entity content URI for a single contact
917            projection,               // The columns to retrieve
918            null,                     // Retrieve all the raw contacts and their data rows.
919            null,                     //
920            sortOrder);               // Sort by the raw contact ID.
921}
922</pre>
923<p>
924    Khi hoàn thành việc tải, {@link android.app.LoaderManager} gọi ra một lệnh gọi lại đến
925    {@link android.app.LoaderManager.LoaderCallbacks#onLoadFinished(Loader, D)
926    onLoadFinished()}. Một trong các tham đối đến với phương pháp này là một
927    {@link android.database.Cursor} với các kết quả của truy vấn. Trong ứng dụng của chính mình, bạn có thể nhận dữ liệu
928    từ {@link android.database.Cursor} này để hiển thị nó hoặc thao tác thêm với nó.
929</p>
930<h3 id="Transactions">Sửa đổi hàng loạt</h3>
931<p>
932    Bất cứ khi nào có thể, bạn nên chèn, cập nhật và xóa dữ liệu trong Trình cung cấp Danh bạ trong
933    "chế độ hàng loạt", bằng cách tạo một {@link java.util.ArrayList} của các đối tượng
934    {@link android.content.ContentProviderOperation} và gọi
935    {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}. Vì
936    Trình cung cấp Danh bạ thực hiện tất cả thao tác trong một
937    {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} trong một giao tác
938    đơn, các sửa đổi của bạn sẽ không bao giờ ra khỏi kho lưu giữ danh bạ một cách
939    không nhất quán. Sửa đổi hàng loạt cũng tạo điều kiện cho việc chèn một liên lạc thô và dữ liệu chi tiết của liên lạc
940    tại cùng thời điểm.
941</p>
942<p class="note">
943    <strong>Lưu ý:</strong> Để sửa đổi một liên lạc thô <em>đơn</em>, hãy xét gửi một ý định tới
944    ứng dụng danh bạ của thiết bị thay vì xử lý sửa đổi trong ứng dụng của bạn.
945    Việc làm này được mô tả chi tiết hơn trong phần
946    <a href="#Intents">Truy xuất và sửa đổi bằng ý định</a>.
947</p>
948<h4>Điểm kết quả</h4>
949<p>
950    Sửa đổi hàng loạt chứa nhiều thao tác có thể chặn các tiến trình khác,
951    dẫn đến trải nghiệm người dùng tổng thể không tốt. Để sắp xếp tổ chức tất cả sửa đổi mà bạn muốn
952    thực hiện trong ít danh sách riêng nhất có thể, và đồng thời ngăn chúng
953    chặn hệ thống, bạn nên đặt các <strong>điểm kết quả</strong> cho một hoặc nhiều thao tác.
954    Điểm kết quả là một đối tượng {@link android.content.ContentProviderOperation} có giá trị
955    {@link android.content.ContentProviderOperation#isYieldAllowed()} được đặt thành
956    <code>true</code>. Khi các Trình cung cấp Danh bạ gặp phải một điểm kết quả, nó tạm dừng công việc để
957    cho phép các tiến trình khác chạy và đóng giao tác hiện tại. Khi trình cung cấp bắt đầu lại, nó
958    tiếp tục với thao tác tiếp theo trong {@link java.util.ArrayList} và bắt đầu một giao tác
959    mới.
960</p>
961<p>
962    Điểm kết quả dẫn đến có nhiều hơn một giao tác trên mỗi lệnh gọi tới
963    {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}. Vì
964    điều này, bạn nên đặt một điểm kết quả cho thao tác cuối cùng đối với một tập hợp các hàng có liên quan.
965    Ví dụ, bạn nên đặt một điểm kết quả cho thao tác cuối cùng trong một tập hợp mà thêm
966    các hàng liên lạc thô và hàng dữ liệu liên kết của chúng, hoặc thao tác cuối cùng đối với một tập hợp các hàng liên quan tới
967    một liên lạc riêng lẻ.
968</p>
969<p>
970    Điểm kết quả cũng là một đơn vị thao tác nguyên tử. Tất cả truy cập giữa hai điểm kết quả sẽ
971    hoặc thành công hoặc thất bại như một đơn vị riêng lẻ. Nếu bạn không đặt bất kỳ điểm kết quả nào, thao tác
972    nguyên tử nhỏ nhất chính là toàn bộ loạt thao tác. Nếu sử dụng điểm kết quả, bạn ngăn cản
973    các thao tác làm giảm hiệu suất của hệ thống, đồng thời đảm bảo rằng một tập con của
974    thao tác là tập nguyên tử.
975</p>
976<h4>Tham chiếu lại sửa đổi</h4>
977<p>
978    Khi bạn đang chèn một hàng liên lạc thô mới và các hàng dữ liệu liên kết của nó như một tập hợp các đối tượng
979    {@link android.content.ContentProviderOperation}, bạn phải liên kết các hàng dữ liệu với
980    hàng liên lạc thô bằng cách chèn giá trị
981    {@code android.provider.BaseColumns#_ID} của liên lạc thô làm giá trị
982    {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID}. Tuy nhiên, giá trị
983    này không có sẵn khi bạn đang tạo {@link android.content.ContentProviderOperation}
984    cho hàng dữ liệu, vì bạn chưa áp dụng
985    {@link android.content.ContentProviderOperation} cho hàng liên lạc thô. Để khắc phục điều này,
986    lớp {@link android.content.ContentProviderOperation.Builder} có phương pháp
987    {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}.
988    Phương pháp này cho phép bạn chèn hoặc sửa đổi một cột bằng
989    kết quả của một thao tác trước đó.
990</p>
991<p>
992    Phương pháp {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}
993    có hai tham đối:
994</p>
995    <dl>
996        <dt>
997            <code>key</code>
998        </dt>
999        <dd>
1000            Khóa của một cặp khóa-giá trị. Giá trị của tham đối này nên là tên của một cột
1001            trong bảng mà bạn đang sửa đổi.
1002        </dd>
1003        <dt>
1004            <code>previousResult</code>
1005        </dt>
1006        <dd>
1007            Chỉ mục dựa trên 0 của một giá trị trong mảng đối tượng
1008            {@link android.content.ContentProviderResult} từ
1009            {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}. Khi
1010            thao tác hàng loạt được áp dụng, kết quả của mỗi thao tác được lưu giữ trong một mảng kết quả
1011            trung gian. Giá trị <code>previousResult</code> là chỉ mục
1012            của một trong những kết quả này, nó được truy xuất và lưu giữ với giá trị <code>key</code>
1013. Điều này cho phép bạn chèn một bản ghi liên lạc thô mới và nhận lại giá trị
1014            {@code android.provider.BaseColumns#_ID} của nó, rồi thực hiện một "tham chiếu ngược" về
1015            giá trị đó khi bạn thêm một hàng {@link android.provider.ContactsContract.Data}.
1016            <p>
1017                Toàn bộ mảng kết quả được tạo khi bạn lần đầu gọi
1018                {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()},
1019                với kích cỡ bằng với kích cỡ của {@link java.util.ArrayList} của các đối tượng
1020                {@link android.content.ContentProviderOperation} mà bạn cung cấp. Tuy nhiên, tất cả
1021                các phần tử trong mảng kết quả được đặt thành <code>null</code>, và nếu bạn cố gắng
1022                thực hiện tham chiếu ngược tới một kết quả cho một thao tác chưa được áp dụng,
1023{@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}
1024                sẽ đưa ra một lỗi {@link java.lang.Exception}.
1025
1026            </p>
1027        </dd>
1028    </dl>
1029<p>
1030    Các đoạn mã HTML sau minh họa cách chèn một liên lạc thô mới và dữ liệu hàng loạt. Chúng
1031    bao gồm mã thiết lập một điểm kết quả và sử dụng một tham chiếu lại. Đoạn mã HTML là một
1032    phiên bản mở rộng của phương pháp <code>createContacEntry()</code>, nó là một phần của lớp
1033    <code>ContactAdder</code> trong ứng dụng mẫu
1034    <code><a href="{@docRoot}resources/samples/ContactManager/index.html">
1035    Contact Manager</a></code>.
1036</p>
1037<p>
1038    Đoạn mã HTML đầu tiên truy xuất dữ liệu liên lạc từ UI. Tại điểm này, người dùng đã
1039    chọn tài khoản mà liên lạc thô mới nên được thêm cho tài khoản đó.
1040</p>
1041<pre>
1042// Creates a contact entry from the current UI values, using the currently-selected account.
1043protected void createContactEntry() {
1044    /*
1045     * Gets values from the UI
1046     */
1047    String name = mContactNameEditText.getText().toString();
1048    String phone = mContactPhoneEditText.getText().toString();
1049    String email = mContactEmailEditText.getText().toString();
1050
1051    int phoneType = mContactPhoneTypes.get(
1052            mContactPhoneTypeSpinner.getSelectedItemPosition());
1053
1054    int emailType = mContactEmailTypes.get(
1055            mContactEmailTypeSpinner.getSelectedItemPosition());
1056</pre>
1057<p>
1058    Đoạn mã HTML tiếp theo tạo một thao tác để chèn hàng liên lạc thô vào bảng
1059    {@link android.provider.ContactsContract.RawContacts}:
1060</p>
1061<pre>
1062    /*
1063     * Prepares the batch operation for inserting a new raw contact and its data. Even if
1064     * the Contacts Provider does not have any data for this person, you can't add a Contact,
1065     * only a raw contact. The Contacts Provider will then add a Contact automatically.
1066     */
1067
1068     // Creates a new array of ContentProviderOperation objects.
1069    ArrayList&lt;ContentProviderOperation&gt; ops =
1070            new ArrayList&lt;ContentProviderOperation&gt;();
1071
1072    /*
1073     * Creates a new raw contact with its account type (server type) and account name
1074     * (user's account). Remember that the display name is not stored in this row, but in a
1075     * StructuredName data row. No other data is required.
1076     */
1077    ContentProviderOperation.Builder op =
1078            ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
1079            .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType())
1080            .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName());
1081
1082    // Builds the operation and adds it to the array of operations
1083    ops.add(op.build());
1084</pre>
1085<p>
1086    Tiếp theo, mã tạo các hàng dữ liệu cho hàng tên hiển thị, điện thoại và e-mail.
1087</p>
1088<p>
1089    Từng đối tượng bộ dựng thao tác sẽ sử dụng
1090    {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}
1091    để nhận
1092    {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID}. Tham chiếu đó sẽ trỏ
1093    ngược về đối tượng {@link android.content.ContentProviderResult} từ thao tác đầu tiên,
1094    là thao tác thêm hàng liên lạc thô và trả về giá trị {@code android.provider.BaseColumns#_ID}
1095    mới của nó. Kết quả là, mỗi hàng dữ liệu được tự động liên kết bởi
1096    {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID}
1097    của nó với hàng {@link android.provider.ContactsContract.RawContacts} mới mà nó thuộc về.
1098</p>
1099<p>
1100    Đối tượng {@link android.content.ContentProviderOperation.Builder} thêm hàng e-mail sẽ được
1101    gắn cờ bằng {@link android.content.ContentProviderOperation.Builder#withYieldAllowed(boolean)
1102    withYieldAllowed()}, mà điều này đặt một điểm kết quả:
1103</p>
1104<pre>
1105    // Creates the display name for the new raw contact, as a StructuredName data row.
1106    op =
1107            ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
1108            /*
1109             * withValueBackReference sets the value of the first argument to the value of
1110             * the ContentProviderResult indexed by the second argument. In this particular
1111             * call, the raw contact ID column of the StructuredName data row is set to the
1112             * value of the result returned by the first operation, which is the one that
1113             * actually adds the raw contact row.
1114             */
1115            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
1116
1117            // Sets the data row's MIME type to StructuredName
1118            .withValue(ContactsContract.Data.MIMETYPE,
1119                    ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
1120
1121            // Sets the data row's display name to the name in the UI.
1122            .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
1123
1124    // Builds the operation and adds it to the array of operations
1125    ops.add(op.build());
1126
1127    // Inserts the specified phone number and type as a Phone data row
1128    op =
1129            ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
1130            /*
1131             * Sets the value of the raw contact id column to the new raw contact ID returned
1132             * by the first operation in the batch.
1133             */
1134            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
1135
1136            // Sets the data row's MIME type to Phone
1137            .withValue(ContactsContract.Data.MIMETYPE,
1138                    ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
1139
1140            // Sets the phone number and type
1141            .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
1142            .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType);
1143
1144    // Builds the operation and adds it to the array of operations
1145    ops.add(op.build());
1146
1147    // Inserts the specified email and type as a Phone data row
1148    op =
1149            ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
1150            /*
1151             * Sets the value of the raw contact id column to the new raw contact ID returned
1152             * by the first operation in the batch.
1153             */
1154            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
1155
1156            // Sets the data row's MIME type to Email
1157            .withValue(ContactsContract.Data.MIMETYPE,
1158                    ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
1159
1160            // Sets the email address and type
1161            .withValue(ContactsContract.CommonDataKinds.Email.ADDRESS, email)
1162            .withValue(ContactsContract.CommonDataKinds.Email.TYPE, emailType);
1163
1164    /*
1165     * Demonstrates a yield point. At the end of this insert, the batch operation's thread
1166     * will yield priority to other threads. Use after every set of operations that affect a
1167     * single contact, to avoid degrading performance.
1168     */
1169    op.withYieldAllowed(true);
1170
1171    // Builds the operation and adds it to the array of operations
1172    ops.add(op.build());
1173</pre>
1174<p>
1175    Đoạn mã HTML cuối cùng hiển thị lệnh gọi tới
1176    {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} mà
1177    chèn liên lạc thô mới và các hàng dữ liệu.
1178</p>
1179<pre>
1180    // Ask the Contacts Provider to create a new contact
1181    Log.d(TAG,"Selected account: " + mSelectedAccount.getName() + " (" +
1182            mSelectedAccount.getType() + ")");
1183    Log.d(TAG,"Creating contact: " + name);
1184
1185    /*
1186     * Applies the array of ContentProviderOperation objects in batch. The results are
1187     * discarded.
1188     */
1189    try {
1190
1191            getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
1192    } catch (Exception e) {
1193
1194            // Display a warning
1195            Context ctx = getApplicationContext();
1196
1197            CharSequence txt = getString(R.string.contactCreationFailure);
1198            int duration = Toast.LENGTH_SHORT;
1199            Toast toast = Toast.makeText(ctx, txt, duration);
1200            toast.show();
1201
1202            // Log exception
1203            Log.e(TAG, "Exception encountered while inserting contact: " + e);
1204    }
1205}
1206</pre>
1207<p>
1208    Thao tác hàng loạt cũng cho phép bạn triển khai <strong>kiểm soát đồng thời lạc quan</strong>,
1209    một phương pháp áp dụng các giao tác sửa đổi mà không phải khóa kho lưu giữ liên quan.
1210    Để sử dụng phương pháp này, bạn áp dụng giao tác đó rồi kiểm tra các sửa đổi khác mà
1211    có thể đã được thực hiện tại cùng thời điểm. Nếu bạn thấy đã diễn ra một sửa đổi không nhất quán,
1212    hãy quay lui giao tác của bạn và thử lại.
1213</p>
1214<p>
1215    Kiểm soát đồng thời lạc quan rất hữu ích đối với thiết bị di động, khi đó mỗi lúc chỉ có một người dùng
1216    và việc truy cập đồng thời vào một kho lưu giữ dữ liệu hiếm khi xảy ra. Vì không sử dụng khóa nên
1217    không bị lãng phí thời gian cho việc thiết đặt khóa hay chờ các giao tác khác nhả khóa của mình.
1218</p>
1219<p>
1220    Để sử dụng kiểm soát đồng thời lạc quan trong khi đang cập nhật một hàng
1221    {@link android.provider.ContactsContract.RawContacts} đơn, hãy làm theo các bước sau:
1222</p>
1223<ol>
1224    <li>
1225        Truy xuất cột {@link android.provider.ContactsContract.SyncColumns#VERSION}
1226        của liên lạc thô cùng với dữ liệu khác mà bạn truy xuất.
1227    </li>
1228    <li>
1229        Tạo một đối tượng {@link android.content.ContentProviderOperation.Builder} phù hợp để
1230        thi hành một ràng buộc, bằng cách sử dụng phương pháp
1231        {@link android.content.ContentProviderOperation#newAssertQuery(Uri)}. Đối với URI nội dung,
1232        sử dụng {@link android.provider.ContactsContract.RawContacts#CONTENT_URI
1233        RawContacts.CONTENT_URI}
1234        với {@code android.provider.BaseColumns#_ID} của liên lạc thô được nối với nó.
1235    </li>
1236    <li>
1237        Đối với đối tượng {@link android.content.ContentProviderOperation.Builder}, hãy gọi
1238        {@link android.content.ContentProviderOperation.Builder#withValue(String, Object)
1239        withValue()} để so sánh cột {@link android.provider.ContactsContract.SyncColumns#VERSION}
1240        với số phiên bản bạn vừa truy xuất.
1241    </li>
1242    <li>
1243        Đối với cùng {@link android.content.ContentProviderOperation.Builder}, hãy gọi
1244        {@link android.content.ContentProviderOperation.Builder#withExpectedCount(int)
1245        withExpectedCount()} để đảm bảo rằng chỉ một hàng được kiểm tra bằng xác nhận này.
1246    </li>
1247    <li>
1248        Gọi {@link android.content.ContentProviderOperation.Builder#build()} để tạo đối tượng
1249        {@link android.content.ContentProviderOperation}, rồi thêm đối tượng này làm
1250        đối tượng đầu tiên trong {@link java.util.ArrayList} mà bạn chuyển cho
1251        {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}.
1252    </li>
1253    <li>
1254        Áp dụng giao tác hàng loạt.
1255    </li>
1256</ol>
1257<p>
1258    Nếu hàng liên lạc thô được cập nhật bởi một thao tác khác giữa thời điểm bạn đọc hàng và
1259    thời điểm bạn cố gắng sửa đổi nó, "xác nhận" {@link android.content.ContentProviderOperation}
1260    sẽ thất bại, và toàn bộ loạt thao tác sẽ được rút khỏi. Sau đó, bạn có thể chọn thử lại
1261    loạt hoặc thực hiện một hành động khác.
1262</p>
1263<p>
1264    Đoạn mã HTML sau minh họa cách tạo một "xác nhận"
1265    {@link android.content.ContentProviderOperation} sau khi truy vấn một liên lạc thô đơn bằng cách sử dụng
1266    một {@link android.content.CursorLoader}:
1267</p>
1268<pre>
1269/*
1270 * The application uses CursorLoader to query the raw contacts table. The system calls this method
1271 * when the load is finished.
1272 */
1273public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor cursor) {
1274
1275    // Gets the raw contact's _ID and VERSION values
1276    mRawContactID = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID));
1277    mVersion = cursor.getInt(cursor.getColumnIndex(SyncColumns.VERSION));
1278}
1279
1280...
1281
1282// Sets up a Uri for the assert operation
1283Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, mRawContactID);
1284
1285// Creates a builder for the assert operation
1286ContentProviderOperation.Builder assertOp = ContentProviderOperation.netAssertQuery(rawContactUri);
1287
1288// Adds the assertions to the assert operation: checks the version and count of rows tested
1289assertOp.withValue(SyncColumns.VERSION, mVersion);
1290assertOp.withExpectedCount(1);
1291
1292// Creates an ArrayList to hold the ContentProviderOperation objects
1293ArrayList ops = new ArrayList&lt;ContentProviderOperationg&gt;;
1294
1295ops.add(assertOp.build());
1296
1297// You would add the rest of your batch operations to "ops" here
1298
1299...
1300
1301// Applies the batch. If the assert fails, an Exception is thrown
1302try
1303    {
1304        ContentProviderResult[] results =
1305                getContentResolver().applyBatch(AUTHORITY, ops);
1306
1307    } catch (OperationApplicationException e) {
1308
1309        // Actions you want to take if the assert operation fails go here
1310    }
1311</pre>
1312<h3 id="Intents">Truy xuất và sửa đổi bằng ý định</h3>
1313<p>
1314    Việc gửi một ý định tới ứng dụng danh bạ của thiết bị cho phép bạn truy cập Trình cung cấp Danh bạ
1315    một cách gián tiếp. Ý định sẽ khởi động UI ứng dụng danh bạ của thiết bị, trong đó người dùng có thể
1316    thực hiện công việc liên quan tới danh bạ. Với kiểu truy cập này, người dùng có thể:
1317    <ul>
1318        <li>Chọn một liên lạc từ danh sách và trả nó về ứng dụng của bạn để làm việc tiếp.</li>
1319        <li>Chỉnh sửa dữ liệu của một liên lạc hiện có.</li>
1320        <li>Chèn một liên lạc thô mới cho bất kỳ tài khoản nào của họ.</li>
1321        <li>Xóa một liên lạc hoặc dữ liệu danh bạ.</li>
1322    </ul>
1323<p>
1324    Nếu người dùng đang chèn hoặc cập nhật dữ liệu, bạn có thể thu thập dữ liệu trước và gửi nó như
1325    một phần của ý định.
1326</p>
1327<p>
1328    Khi bạn sử dụng ý định để truy cập Trình cung cấp Danh bạ thông qua ứng dụng danh bạ của thiết bị, bạn
1329    không phải ghi UI hay mã của chính mình để truy nhập trình cung cấp. Bạn cũng không phải
1330    yêu cầu quyền đọc hoặc ghi đến trình cung cấp. Ứng dụng danh bạ của thiết bị có thể
1331    cấp quyền đọc đối với một liên lạc cho bạn, và vì bạn đang thực hiện sửa đổi đối với
1332    trình cung cấp thông qua một ứng dụng khác, bạn không cần phải có quyền ghi.
1333</p>
1334<p>
1335    Tiến trình chung để gửi một ý định nhằm truy cập một trình cung cấp được mô tả chi tiết trong hướng dẫn
1336    <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
1337    Nội dung Cơ bản về Trình cung cấp Nội dung</a> trong phần "Truy cập dữ liệu thông qua ý định." Hành động,
1338    kiểu MIME, và các giá trị dữ liệu bạn sử dụng cho các tác vụ có sẵn được tóm tắt trong Bảng 4, trong khi các giá trị
1339    phụ thêm mà bạn có thể sử dụng với
1340    {@link android.content.Intent#putExtra(String, String) putExtra()} được liệt kê trong
1341    tài liệu tham khảo cho {@link android.provider.ContactsContract.Intents.Insert}:
1342</p>
1343<p class="table-caption" id="table4">
1344  <strong>Bảng 4.</strong> Ý định của Trình cung cấp Danh bạ.
1345</p>
1346<table style="width:75%">
1347    <tr>
1348        <th scope="col" style="width:10%">Tác vụ</th>
1349        <th scope="col" style="width:5%">Hành động</th>
1350        <th scope="col" style="width:10%">Dữ liệu</th>
1351        <th scope="col" style="width:10%">Kiểu MIME</th>
1352        <th scope="col" style="width:25%">Lưu ý</th>
1353    </tr>
1354    <tr>
1355        <td><strong>Chọn một liên lạc từ danh sách</strong></td>
1356        <td>{@link android.content.Intent#ACTION_PICK}</td>
1357        <td>
1358            Một trong:
1359            <ul>
1360                <li>
1361{@link android.provider.ContactsContract.Contacts#CONTENT_URI Contacts.CONTENT_URI},
1362                    mà hiển thị một danh sách các liên lạc.
1363                </li>
1364                <li>
1365{@link android.provider.ContactsContract.CommonDataKinds.Phone#CONTENT_URI Phone.CONTENT_URI},
1366                    mà hiển thị một danh sách các số điện thoại cho một liên lạc thô.
1367                </li>
1368                <li>
1369{@link android.provider.ContactsContract.CommonDataKinds.StructuredPostal#CONTENT_URI
1370StructuredPostal.CONTENT_URI},
1371                    mà hiển thị một danh sách các địa chỉ bưu điện cho một liên lạc thô.
1372                </li>
1373                <li>
1374{@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_URI Email.CONTENT_URI},
1375                    mà hiển thị một danh sách các địa chỉ e-mail cho một liên lạc thô.
1376                </li>
1377            </ul>
1378        </td>
1379        <td>
1380            Không sử dụng
1381        </td>
1382        <td>
1383            Hiển thị một danh sách các liên lạc thô hoặc danh sách dữ liệu từ một liên lạc thô, tùy vào kiểu
1384            URI nội dung mà bạn cung cấp.
1385            <p>
1386                Gọi
1387         {@link android.app.Activity#startActivityForResult(Intent, int) startActivityForResult()},
1388                nó trả về URI nội dung của hàng được chọn. Hình thức của URI là URI nội dung
1389                của bảng với <code>LOOKUP_ID</code> của hàng được nối với nó.
1390                Ứng dụng danh bạ của thiết bị cấp quyền đọc và ghi cho URI nội dung này
1391                trong suốt thời gian hoạt động của bạn. Xem hướng dẫn
1392                <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
1393                Nội dung Cơ bản về Trình cung cấp Nội dung</a> để biết thêm chi tiết.
1394            </p>
1395        </td>
1396    </tr>
1397    <tr>
1398        <td><strong>Chèn một liên lạc thô mới</strong></td>
1399        <td>{@link android.provider.ContactsContract.Intents.Insert#ACTION Insert.ACTION}</td>
1400        <td>Không áp dụng</td>
1401        <td>
1402            {@link android.provider.ContactsContract.RawContacts#CONTENT_TYPE
1403            RawContacts.CONTENT_TYPE}, kiểu MIME cho một tập hợp liên các lạc thô.
1404        </td>
1405        <td>
1406            Hiển thị màn hình <strong>Thêm Liên lạc</strong> của ứng dụng danh bạ của thiết bị. Các
1407            giá trị phụ thêm mà bạn thêm vào ý định sẽ được hiển thị. Nếu được gửi bằng
1408        {@link android.app.Activity#startActivityForResult(Intent, int) startActivityForResult()},
1409            URI nội dung của liên lạc thô mới thêm sẽ được chuyển lại cho phương pháp gọi lại
1410            {@link android.app.Activity#onActivityResult(int, int, Intent) onActivityResult()}
1411            của hoạt động của bạn trong tham đối {@link android.content.Intent}, trong
1412            trường "dữ liệu". Để nhận giá trị, hãy gọi {@link android.content.Intent#getData()}.
1413        </td>
1414    </tr>
1415    <tr>
1416        <td><strong>Chỉnh sửa một liên lạc</strong></td>
1417        <td>{@link android.content.Intent#ACTION_EDIT}</td>
1418        <td>
1419            {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI} đối với
1420            liên lạc. Hoạt động của trình chỉnh sửa sẽ cho phép người dùng chỉnh sửa bất kỳ dữ liệu nào được liên kết
1421            với liên lạc này.
1422        </td>
1423        <td>
1424            {@link android.provider.ContactsContract.Contacts#CONTENT_ITEM_TYPE
1425            Contacts.CONTENT_ITEM_TYPE}, một liên lạc đơn.</td>
1426        <td>
1427            Hiển thị màn hình Chỉnh sửa Liên lạc trong ứng dụng danh bạ. Các giá trị phụ thêm mà bạn thêm
1428            vào ý định sẽ được hiển thị. Khi người dùng nhấp vào <strong>Xong</strong> để lưu các
1429            chỉnh sửa, hoạt động của bạn quay lại tiền cảnh.
1430        </td>
1431    </tr>
1432    <tr>
1433        <td><strong>Hiển thị một trình chọn mà cũng có thể thêm dữ liệu.</strong></td>
1434        <td>{@link android.content.Intent#ACTION_INSERT_OR_EDIT}</td>
1435        <td>
1436            Không áp dụng
1437        </td>
1438        <td>
1439            {@link android.provider.ContactsContract.Contacts#CONTENT_ITEM_TYPE}
1440        </td>
1441         <td>
1442            Ý định này luôn hiển thị màn hình bộ chọn của ứng dụng danh bạ. Người dùng có thể hoặc
1443            chọn một liên lạc để chỉnh sửa, hoặc thêm một liên lạc mới. Hoặc màn hình chỉnh sửa hoặc màn hình thêm
1444            sẽ xuất hiện, tùy vào lựa chọn của người dùng, và dữ liệu phụ thêm mà bạn chuyển trong ý định
1445           sẽ được hiển thị. Nếu ứng dụng của bạn hiển thị dữ liệu chẳng hạn như e-mail hoặc số điện thoại, hãy sử dụng
1446            ý định này để cho phép người dùng thêm dữ liệu vào một liên lạc hiện tại.
1447            liên lạc,
1448            <p class="note">
1449                <strong>Lưu ý:</strong> Không cần gửi một giá trị tên trong phần phụ thêm của ý định,
1450                vì người dùng luôn chọn một tên hiện có hoặc thêm một tên mới. Thêm nữa,
1451                nếu bạn gửi một tên, và người dùng chọn thực hiện chỉnh sửa, ứng dụng danh bạ sẽ
1452                hiển thị tên mà bạn gửi, ghi đè giá trị trước. Nếu người dùng không
1453                để ý thấy điều này và lưu chỉnh sửa, giá trị cũ sẽ bị mất.
1454            </p>
1455         </td>
1456    </tr>
1457</table>
1458<p>
1459    Ứng dụng danh bạ của thiết bị không cho phép bạn xóa một liên lạc thô hay bất kỳ dữ liệu nào bằng một
1460    ý định. Thay vào đó, để xóa một liên lạc thô, hãy sử dụng
1461    {@link android.content.ContentResolver#delete(Uri, String, String[]) ContentResolver.delete()}
1462    hoặc {@link android.content.ContentProviderOperation#newDelete(Uri)
1463    ContentProviderOperation.newDelete()}.
1464</p>
1465<p>
1466    Đoạn mã HTML sau minh họa cách xây dựng và gửi một ý định để chèn một liên lạc thô mới và
1467    dữ liệu:
1468</p>
1469<pre>
1470// Gets values from the UI
1471String name = mContactNameEditText.getText().toString();
1472String phone = mContactPhoneEditText.getText().toString();
1473String email = mContactEmailEditText.getText().toString();
1474
1475String company = mCompanyName.getText().toString();
1476String jobtitle = mJobTitle.getText().toString();
1477
1478// Creates a new intent for sending to the device's contacts application
1479Intent insertIntent = new Intent(ContactsContract.Intents.Insert.ACTION);
1480
1481// Sets the MIME type to the one expected by the insertion activity
1482insertIntent.setType(ContactsContract.RawContacts.CONTENT_TYPE);
1483
1484// Sets the new contact name
1485insertIntent.putExtra(ContactsContract.Intents.Insert.NAME, name);
1486
1487// Sets the new company and job title
1488insertIntent.putExtra(ContactsContract.Intents.Insert.COMPANY, company);
1489insertIntent.putExtra(ContactsContract.Intents.Insert.JOB_TITLE, jobtitle);
1490
1491/*
1492 * Demonstrates adding data rows as an array list associated with the DATA key
1493 */
1494
1495// Defines an array list to contain the ContentValues objects for each row
1496ArrayList&lt;ContentValues&gt; contactData = new ArrayList&lt;ContentValues&gt;();
1497
1498
1499/*
1500 * Defines the raw contact row
1501 */
1502
1503// Sets up the row as a ContentValues object
1504ContentValues rawContactRow = new ContentValues();
1505
1506// Adds the account type and name to the row
1507rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType());
1508rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName());
1509
1510// Adds the row to the array
1511contactData.add(rawContactRow);
1512
1513/*
1514 * Sets up the phone number data row
1515 */
1516
1517// Sets up the row as a ContentValues object
1518ContentValues phoneRow = new ContentValues();
1519
1520// Specifies the MIME type for this data row (all data rows must be marked by their type)
1521phoneRow.put(
1522        ContactsContract.Data.MIMETYPE,
1523        ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
1524);
1525
1526// Adds the phone number and its type to the row
1527phoneRow.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
1528
1529// Adds the row to the array
1530contactData.add(phoneRow);
1531
1532/*
1533 * Sets up the email data row
1534 */
1535
1536// Sets up the row as a ContentValues object
1537ContentValues emailRow = new ContentValues();
1538
1539// Specifies the MIME type for this data row (all data rows must be marked by their type)
1540emailRow.put(
1541        ContactsContract.Data.MIMETYPE,
1542        ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE
1543);
1544
1545// Adds the email address and its type to the row
1546emailRow.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email);
1547
1548// Adds the row to the array
1549contactData.add(emailRow);
1550
1551/*
1552 * Adds the array to the intent's extras. It must be a parcelable object in order to
1553 * travel between processes. The device's contacts app expects its key to be
1554 * Intents.Insert.DATA
1555 */
1556insertIntent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contactData);
1557
1558// Send out the intent to start the device's contacts app in its add contact activity.
1559startActivity(insertIntent);
1560</pre>
1561<h3 id="DataIntegrity">Toàn vẹn dữ liệu</h3>
1562<p>
1563    Vì kho lưu giữ danh bạ chứa dữ liệu quan trọng và nhạy cảm mà người dùng cho là
1564    đúng và cập nhật, Trình cung cấp Danh bạ có các quy tắc về toàn vẹn dữ liệu được định nghĩa rõ ràng. Bạn có
1565    trách nhiệm tuân theo những quy tắc này khi sửa đổi dữ liệu danh bạ. Các quy tắc
1566    quan trọng được liệt kê ở đây:
1567</p>
1568<dl>
1569    <dt>
1570        Luôn thêm một hàng {@link android.provider.ContactsContract.CommonDataKinds.StructuredName} cho
1571        mỗi hàng {@link android.provider.ContactsContract.RawContacts} mà bạn thêm.
1572    </dt>
1573    <dd>
1574        Hàng {@link android.provider.ContactsContract.RawContacts} không có một hàng
1575        {@link android.provider.ContactsContract.CommonDataKinds.StructuredName} trong bảng
1576        {@link android.provider.ContactsContract.Data} có thể gây ra sự cố trong khi
1577        tổng hợp.
1578    </dd>
1579    <dt>
1580        Luôn liên kết các hàng {@link android.provider.ContactsContract.Data} mới với hàng
1581        {@link android.provider.ContactsContract.RawContacts} mẹ của chúng.
1582    </dt>
1583    <dd>
1584        Mỗi hàng {@link android.provider.ContactsContract.Data} mà không được liên kết với một
1585        {@link android.provider.ContactsContract.RawContacts} sẽ không hiển thị trong ứng dụng danh bạ
1586         của thiết bị, và nó có thể gây ra sự cố với trình điều hợp đồng bộ.
1587    </dd>
1588    <dt>
1589        Chỉ thay đổi dữ liệu đối với những liên lạc thô mà bạn sở hữu.
1590    </dt>
1591    <dd>
1592        Nhớ rằng Trình cung cấp Danh bạ luôn quản lý dữ liệu từ vài
1593        loại tài khoản/dịch vụ trực tuyến khác nhau. Bạn cần đảm bảo rằng ứng dụng của bạn chỉ sửa đổi
1594        hoặc xóa dữ liệu đối với các hàng thuộc về bạn, và rằng nó chỉ chèn dữ liệu có
1595        loại và tên tài khoản mà bạn kiểm soát.
1596    </dd>
1597    <dt>
1598        Luôn sử dụng các hằng số được định nghĩa trong {@link android.provider.ContactsContract} và các lớp con của nó
1599        đối với thẩm quyền, URI nội dung, đường dẫn URI, tên cột, kiểu MIME, và các giá trị
1600        {@link android.provider.ContactsContract.CommonDataKinds.CommonColumns#TYPE}.
1601    </dt>
1602    <dd>
1603        Sử dụng những hằng số này sẽ giúp bạn tránh gặp lỗi. Bạn cũng sẽ được thông báo bằng cảnh báo
1604        từ trình biên dịch nếu bất kỳ hằng số nào không được chấp nhận.
1605    </dd>
1606</dl>
1607<h3 id="CustomData">Hàng dữ liệu tùy chỉnh</h3>
1608<p>
1609    Bằng cách tạo và sử dụng các kiểu MIME tùy chỉnh của chính mình, bạn có thể chèn, chỉnh sửa, xóa và truy xuất
1610    các hàng dữ liệu của chính mình trong bảng {@link android.provider.ContactsContract.Data}. Các hàng của bạn
1611    bị giới hạn bằng cách sử dụng cột được định nghĩa trong
1612    {@link android.provider.ContactsContract.DataColumns}, mặc dù bạn có thể ánh xạ
1613    tên cột theo kiểu của chính mình với tên cột mặc định. Trong ứng dụng danh bạ của thiết bị,
1614    dữ liệu cho các hàng của bạn được hiển thị nhưng không thể chỉnh sửa hay xóa được, và người dùng không thể thêm
1615    dữ liệu bổ sung. Để cho phép người dùng sửa đổi các hàng dữ liệu tùy chỉnh của mình, bạn phải cung cấp một hoạt động
1616    trình chỉnh sửa trong ứng dụng của chính mình.
1617</p>
1618<p>
1619    Để hiển thị dữ liệu tùy chỉnh của mình, hãy cung cấp một tệp <code>contacts.xml</code> chứa một phần tử
1620    <code>&lt;ContactsAccountType&gt;</code> và một hoặc nhiều phần tử con
1621    <code>&lt;ContactsDataKind&gt;</code> của nó. Điều này được mô tả chi tiết hơn trong
1622    phần <a href="#SocialStreamDataKind"><code>&lt;ContactsDataKind&gt; element</code></a>.
1623</p>
1624<p>
1625    Để tìm hiểu thêm về các kiểu MIME tùy chỉnh, hãy đọc hướng dẫn
1626    <a href="{@docRoot}guide/topics/providers/content-provider-creating.html">
1627    Tạo một Trình cung cấp Nội dung</a>.
1628</p>
1629<h2 id="SyncAdapters">Trình điều hợp Đồng bộ Trình cung cấp Danh bạ</h2>
1630<p>
1631    Trình cung cấp Danh bạ được thiết kế riêng để xử lý <strong>đồng bộ hoá</strong>
1632    dữ liệu danh bạ giữa một thiết bị và một dịch vụ trực tuyến. Điều này cho phép người dùng tải
1633    dữ liệu hiện có xuống một thiết bị mới và tải dữ liệu hiện có lên một tài khoản mới.
1634    Đồng bộ hoá cũng đảm bảo rằng người dùng có sẵn dữ liệu mới nhất, không phụ thuộc vào
1635    nguồn của các bổ sung và thay đổi. Một ưu điểm khác của đồng bộ hoá đó là nó khiến
1636    dữ liệu danh bạ có sẵn ngay cả khi thiết bị không được kết nối với mạng.
1637</p>
1638<p>
1639    Mặc dù bạn có thể triển khai đồng bộ hoá theo nhiều cách, hệ thống Android cung cấp
1640    một khuôn khổ đồng bộ hóa bổ trợ có khả năng tự động hóa những tác vụ sau:
1641    <ul>
1642
1643    <li>
1644        Kiểm tra sự sẵn sàng của mạng.
1645    </li>
1646    <li>
1647        Lập lịch biểu và thực hiện đồng bộ hoá dựa trên tùy chọn của người dùng.
1648    </li>
1649    <li>
1650        Khởi động lại những đồng bộ hoá đã dừng.
1651    </li>
1652    </ul>
1653<p>
1654    Để sử dụng khuôn khổ này, bạn phải cung cấp một phần bổ trợ trình điều hợp đồng bộ. Mỗi trình điều hợp đồng bộ là duy nhất đối với
1655    một dịch vụ và trình cung cấp nội dung, nhưng có thể xử lý nhiều tên tài khoản cho cùng dịch vụ. Khuôn khổ
1656    cũng cho phép nhiều trình điều hợp đồng bộ cho cùng dịch vụ và trình cung cấp.
1657</p>
1658<h3 id="SyncClassesFiles">Các lớp và tệp trình điều hợp đồng bộ</h3>
1659<p>
1660    Bạn triển khai một trình điều hợp đồng bộ làm lớp con của
1661    {@link android.content.AbstractThreadedSyncAdapter} và cài đặt nó như một phần của một ứng dụng
1662    Android. Hệ thống biết về trình điều hợp đồng bộ từ các phần tử trong bản kê khai ứng dụng
1663    của nó, và từ một tệp XML đặc biệt được chỉ đến trong bản kê khai. Tệp XML sẽ định nghĩa
1664    loại tài khoản cho dịch vụ trực tuyến và thẩm quyền cho trình cung cấp nội dung, cùng nhau chúng
1665   xác định duy nhất một trình điều hợp. Trình điều hợp đồng bộ không được kích hoạt cho tới khi người dùng thêm một
1666    tài khoản cho loại tài khoản của trình điều hợp đồng bộ và kích hoạt đồng bộ hoá cho trình cung cấp
1667    nội dung mà trình điều hợp đồng bộ sẽ đồng bộ cùng.  Tại thời điểm đó, hệ thống bắt đầu quản lý trình điều hợp,
1668    gọi nó nếu cần thiết để đồng bộ hoá giữa trình cung cấp nội dung và máy chủ.
1669</p>
1670<p class="note">
1671    <strong>Lưu ý:</strong> Việc sử dụng một loại tài khoản để tham gia nhận biết trình điều hợp đồng bộ sẽ cho phép
1672    hệ thống phát hiện và nhóm cùng nhau những trình điều hợp đồng bộ truy cập các dịch vụ khác nhau từ
1673    cùng tổ chức. Ví dụ, các trình điều hợp đồng bộ cho dịch vụ trực tuyến của Google đều có cùng
1674    loại tài khoản <code>com.google</code>. Khi người dùng thêm một tài khoản Google vào thiết bị của mình, tất cả
1675    trình điều hợp đồng bộ được cài đặt cho dịch vụ Google được liệt kê cùng nhau; mỗi trình điều hợp đồng bộ
1676    được liệt kê sẽ đồng bộ với một trình cung cấp nội dung khác nhau trên thiết bị.
1677</p>
1678<p>
1679    Vì hầu hết dịch vụ đều yêu cầu người dùng xác minh danh tính của họ trước khi truy cập
1680    dữ liệu, hệ thống Android cung cấp một khuôn khổ xác thực tương tự như và thường
1681    được sử dụng cùng với khuôn khổ của trình điều hợp đồng bộ. Khuôn khổ xác thực sử dụng
1682    các trình xác thực bổ trợ là lớp con của
1683    {@link android.accounts.AbstractAccountAuthenticator}. Một trình xác thực sẽ xác minh
1684    danh tính của người dùng theo các bước sau:
1685    <ol>
1686        <li>
1687            Thu thập tên, mật khẩu hoặc thông tin tương tự của người dùng (
1688<strong>thông tin xác thực</strong> của người dùng).
1689        </li>
1690        <li>
1691            Gửi thông tin xác thực tới dịch vụ
1692        </li>
1693        <li>
1694            Kiểm tra trả lời của dịch vụ.
1695        </li>
1696    </ol>
1697<p>
1698    Nếu dịch vụ chấp nhận thông tin xác thực, trình xác thực có thể
1699    lưu giữ thông tin xác thực đó để sử dụng sau. Vì khuôn khổ trình xác thực bổ trợ,
1700    {@link android.accounts.AccountManager} có thể cung cấp quyền truy cập bất kỳ token xác thực nào mà một trình xác thực
1701    hỗ trợ và chọn hiện ra, chẳng hạn như token xác thực OAuth2.
1702</p>
1703<p>
1704    Mặc dù không yêu cầu xác thực, phần lớn dịch vụ danh bạ đều sử dụng nó.
1705    Tuy nhiên, bạn không phải sử dụng khuôn khổ xác thực của Android để thực hiện xác thực.
1706</p>
1707<h3 id="SyncAdapterImplementing">Triển khai trình điều hợp đồng bộ</h3>
1708<p>
1709    Để triển khai một trình điều hợp đồng bộ cho Trình cung cấp Danh bạ, bạn bắt đầu bằng cách tạo một
1710    ứng dụng Android chứa:
1711</p>
1712    <dl>
1713        <dt>
1714            Một thành phần {@link android.app.Service} để hồi đáp lại các yêu cầu từ hệ thống nhằm
1715            gắn kết với trình điều hợp đồng bộ.
1716        </dt>
1717        <dd>
1718            Khi hệ thống muốn chạy đồng bộ hoá, nó gọi phương pháp
1719            {@link android.app.Service#onBind(Intent) onBind()} của dịch vụ và nhận một
1720            {@link android.os.IBinder} cho trình điều hợp đồng bộ. Điều này cho phép hệ thống thực hiện
1721            lệnh gọi liên tiến trình tới các phương pháp của trình điều hợp.
1722            <p>
1723                Trong ứng dụng mẫu<a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
1724                Trình điều hợp Đồng bộ Mẫu</a>, tên lớp của dịch vụ này là
1725                <code>com.example.android.samplesync.syncadapter.SyncService</code>.
1726            </p>
1727        </dd>
1728        <dt>
1729            Trình điều hợp đồng bộ thực tế, được triển khai như một lớp con cụ thể của
1730            {@link android.content.AbstractThreadedSyncAdapter}.
1731        </dt>
1732        <dd>
1733            Lớp này thực hiện công việc tải xuống dữ liệu từ máy chủ, tải lên dữ liệu từ
1734            thiết bị, và xử lý xung đột. Công việc chính của trình điều hợp được
1735            thực hiện trong phương pháp {@link android.content.AbstractThreadedSyncAdapter#onPerformSync(
1736            Account, Bundle, String, ContentProviderClient, SyncResult)
1737            onPerformSync()}. Lớp này phải được khởi tạo như một đối tượng duy nhất (singleton).
1738            <p>
1739                Trong ứng dụng mẫu <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
1740                Trình điều hợp Đồng bộ Mẫu</a>, trình điều hợp đồng bộ được định nghĩa trong lớp
1741                <code>com.example.android.samplesync.syncadapter.SyncAdapter</code>.
1742            </p>
1743        </dd>
1744        <dt>
1745            Một lớp con của {@link android.app.Application}.
1746        </dt>
1747        <dd>
1748            Lớp này đóng vai trò như một nhà máy cho đối tượng duy nhất của trình điều hợp đồng bộ. Sử dụng phương pháp
1749            {@link android.app.Application#onCreate()} để khởi tạo trình điều hợp đồng bộ, và
1750            cung cấp một phương pháp "bộ nhận" tĩnh để trả đối tượng duy nhất về phương pháp
1751            {@link android.app.Service#onBind(Intent) onBind()} của dịch vụ
1752            của trình điều hợp đồng bộ.
1753        </dd>
1754        <dt>
1755            <strong>Tùy chọn:</strong> Một thành phần {@link android.app.Service} để hồi đáp lại
1756            các yêu cầu từ hệ thống về xác thực người dùng.
1757        </dt>
1758        <dd>
1759            {@link android.accounts.AccountManager} khởi động dịch vụ này để bắt đầu tiến trình
1760            xác thực. Phương pháp {@link android.app.Service#onCreate()} của dịch vụ này sẽ khởi tạo một
1761            đối tượng trình xác thực. Khi hệ thống muốn xác thực một tài khoản người dùng cho trình điều hợp đồng bộ
1762            của ứng dụng, nó sẽ gọi phương pháp
1763            {@link android.app.Service#onBind(Intent) onBind()} của dịch vụ để nhận một
1764            {@link android.os.IBinder} cho trình xác thực. Điều này cho phép hệ thống thực hiện
1765            lệnh gọi liên tiến trình tới các phương pháp của trình xác thực.
1766            <p>
1767                Trong ứng dụng mẫu<a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
1768                Trình điều hợp Đồng bộ Mẫu</a>, tên lớp của dịch vụ này là
1769                <code>com.example.android.samplesync.authenticator.AuthenticationService</code>.
1770            </p>
1771        </dd>
1772        <dt>
1773            <strong>Tùy chọn:</strong> Một lớp con cụ thể của
1774            {@link android.accounts.AbstractAccountAuthenticator} để xử lý các yêu cầu về
1775            xác thực.
1776        </dt>
1777        <dd>
1778            Lớp này cung cấp các phương pháp mà {@link android.accounts.AccountManager} gọi ra
1779            để xác thực các thông tin xác thực của người dùng với máy chủ. Các chi tiết của
1780            tiến trình xác thực rất khác nhau dựa trên công nghệ máy chủ đang sử dụng. Bạn nên
1781            tham khảo tài liệu cho phần mềm máy chủ của mình để tìm hiểu thêm về xác thực.
1782            <p>
1783                Trong ứng dụng mẫu <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
1784                Trình điều hợp Đồng bộ Mẫu</a>, trình xác thực được định nghĩa trong lớp
1785                <code>com.example.android.samplesync.authenticator.Authenticator</code>.
1786            </p>
1787        </dd>
1788        <dt>
1789            Các tệp XML để định nghĩa trình điều hợp đồng bộ và trình xác thực cho hệ thống.
1790        </dt>
1791        <dd>
1792            Các thành phần dịch vụ trình điều hợp đồng bộ và trình xác thực đã nêu được
1793            định nghĩa trong các phần tử
1794<code>&lt;<a href="{@docRoot}guide/topics/manifest/service-element.html">service</a>&gt;</code>
1795            ở bản kê khai của ứng dụng. Những phần tử này
1796            chứa các phần tử con
1797<code>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</code>
1798mà cung cấp dữ liệu cụ thể cho
1799            hệ thống:
1800            <ul>
1801                <li>
1802                    Phần tử
1803<code>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</code>
1804                    cho dịch vụ trình điều hợp đồng bộ sẽ trỏ về
1805                    tệp XML <code>res/xml/syncadapter.xml</code>. Đến lượt mình, tệp này quy định
1806                    một URI cho dịch vụ web mà sẽ được đồng bộ hóa với Trình cung cấp Danh bạ,
1807                    và một loại tài khoản cho dịch vụ web.
1808                </li>
1809                <li>
1810                    <strong>Tùy chọn:</strong> Phần tử
1811<code>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</code>
1812                    cho trình xác thực sẽ trỏ về tệp XML
1813                    <code>res/xml/authenticator.xml</code>. Đến lượt mình, tệp này quy định
1814                    loại tài khoản mà trình xác thực này hỗ trợ, cũng như các tài nguyên UI mà
1815                    xuất hiện trong tiến trình xác thực. Loại tài khoản được quy định trong phần tử
1816                    này phải giống như loại tài khoản được quy định cho trình điều hợp
1817                    đồng bộ.
1818                </li>
1819            </ul>
1820        </dd>
1821    </dl>
1822<h2 id="SocialStream">Dữ liệu từ Luồng Xã hội</h2>
1823<p>
1824    Các bảng {@code android.provider.ContactsContract.StreamItems} và
1825    {@code android.provider.ContactsContract.StreamItemPhotos} quản lý
1826    dữ liệu đến từ các mạng xã hội. Bạn có thể ghi một trình điều hợp đồng bộ mà thêm dữ liệu luồng từ
1827    mạng của chính mình vào những bảng này, hoặc bạn có thể đọc dữ liệu luồng từ những bảng này và
1828    hiển thị nó trong ứng dụng của chính mình, hoặc cả hai. Với những tính năng này, các dịch vụ và ứng dụng
1829    mạng xã hội của bạn có thể được tích hợp vào trải nghiệm mạng xã hội của Android.
1830</p>
1831<h3 id="StreamText">Văn bản từ luồng xã hội</h3>
1832<p>
1833    Các mục dòng dữ liệu luôn được liên kết với một liên lạc thô.
1834    {@code android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID} liên kết với giá trị
1835    <code>_ID</code> của liên lạc thô mới. Loại tài khoản và tên tài khoản của liên lạc thô
1836    cũng được lưu giữ trong hàng mục dòng.
1837</p>
1838<p>
1839    Lưu giữ dữ liệu từ luồng của bạn vào những cột sau:
1840</p>
1841<dl>
1842    <dt>
1843        {@code android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_TYPE}
1844    </dt>
1845    <dd>
1846        <strong>Bắt buộc.</strong> Loại tài khoản của người dùng đối với liên lạc thô được liên kết với mục dòng
1847        này. Nhớ đặt giá trị này khi bạn chèn một mục dòng.
1848    </dd>
1849    <dt>
1850        {@code android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_NAME}
1851    </dt>
1852    <dd>
1853        <strong>Bắt buộc.</strong> Tên tài khoản của người dùng đối với liên lạc thô được liên kết với mục dòng
1854        này. Nhớ đặt giá trị này khi bạn chèn một mục dòng.
1855    </dd>
1856    <dt>
1857        Cột mã định danh
1858    </dt>
1859    <dd>
1860        <strong>Bắt buộc.</strong> Bạn phải chèn các cột mã định danh sau khi chèn
1861        một mục dòng:
1862        <ul>
1863            <li>
1864                {@code android.provider.ContactsContract.StreamItemsColumns#CONTACT_ID}: Giá trị
1865                {@code android.provider.BaseColumns#_ID} của liên lạc mà mục dòng
1866                này được liên kết với.
1867            </li>
1868            <li>
1869                {@code android.provider.ContactsContract.StreamItemsColumns#CONTACT_LOOKUP_KEY}: Giá trị
1870                {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} của liên lạc
1871                mà mục dòng này được liên kết với.
1872            </li>
1873            <li>
1874                {@code android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID}: Giá trị
1875                {@code android.provider.BaseColumns#_ID} của liên lạc thô mà mục dòng này
1876                được liên kết với.
1877            </li>
1878        </ul>
1879    </dd>
1880    <dt>
1881        {@code android.provider.ContactsContract.StreamItemsColumns#COMMENTS}
1882    </dt>
1883    <dd>
1884        Tùy chọn. Lưu giữ thông tin tóm tắt mà bạn có thể hiển thị ở phần đầu của một mục dòng.
1885    </dd>
1886    <dt>
1887        {@code android.provider.ContactsContract.StreamItemsColumns#TEXT}
1888    </dt>
1889    <dd>
1890        Văn bản của mục dòng, hoặc là nội dung đã được đăng bởi nguồn của mục đó,
1891        hoặc là mô tả về một số hành động đã khởi tạo mục dòng. Cột này có thể chứa
1892        bất kỳ hình ảnh tài nguyên định dạng và được nhúng nào mà có thể được kết xuất bởi
1893        {@link android.text.Html#fromHtml(String) fromHtml()}. Trình cung cấp có thể cắt bớt hoặc
1894        cắt ngắn bằng dấu ba chấm các nội dung dài, nhưng sẽ cố gắng tránh làm hỏng các tag.
1895    </dd>
1896    <dt>
1897        {@code android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP}
1898    </dt>
1899    <dd>
1900        Xâu văn bản chứa thời gian mà mục dòng được chèn hoặc cập nhật, có
1901        dạng <em>mili giây</em> trôi qua kể từ giờ epoch. Những ứng dụng chèn hoặc cập nhật mục dòng sẽ chịu
1902        trách nhiệm  duy trì cột này; nó không được tự động duy trì bởi
1903        Trình cung cấp Danh bạ.
1904    </dd>
1905</dl>
1906<p>
1907    Để hiển thị thông tin nhận dạng cho các mục dòng của bạn, hãy sử dụng
1908    {@code android.provider.ContactsContract.StreamItemsColumns#RES_ICON},
1909    {@code android.provider.ContactsContract.StreamItemsColumns#RES_LABEL}, và
1910    {@code android.provider.ContactsContract.StreamItemsColumns#RES_PACKAGE} để liên kết với các tài nguyên
1911    trong ứng dụng của mình.
1912</p>
1913<p>
1914    Bảng {@code android.provider.ContactsContract.StreamItems} chứa các cột
1915    {@code android.provider.ContactsContract.StreamItemsColumns#SYNC1} thông qua
1916    {@code android.provider.ContactsContract.StreamItemsColumns#SYNC4} dành riêng để sử dụng
1917    trình điều hợp đồng bộ.
1918</p>
1919<h3 id="StreamPhotos">Ảnh từ luồng xã hội</h3>
1920<p>
1921   Bảng {@code android.provider.ContactsContract.StreamItemPhotos} lưu giữ ảnh được liên kết
1922   với một mục dòng. Cột
1923   {@code android.provider.ContactsContract.StreamItemPhotosColumns#STREAM_ITEM_ID} của bảng
1924   liên kết với các giá trị trong {@code android.provider.BaseColumns#_ID} của bảng
1925   {@code android.provider.ContactsContract.StreamItems}. Các tham chiếu ảnh được lưu giữ trong
1926   bảng ở những cột này:
1927</p>
1928<dl>
1929    <dt>
1930        Cột {@code android.provider.ContactsContract.StreamItemPhotos#PHOTO} (một BLOB).
1931    </dt>
1932    <dd>
1933        Biểu diễn dạng nhị phân của ảnh, được trình cung cấp đổi kích cỡ để lưu giữ và hiển thị.
1934        Cột này có sẵn để tương thích ngược với các phiên bản trước của Trình cung cấp
1935        Danh bạ mà đã sử dụng nó để lưu giữ ảnh. Tuy nhiên, trong phiên bản hiện tại
1936        bạn không nên sử dụng cột này để lưu giữ ảnh. Thay vào đó, hãy sử dụng
1937        hoặc {@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID} hoặc
1938        {@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI} (cả hai
1939        đều được mô tả trong các điểm sau) để lưu giữ ảnh trong một tệp. Lúc này, cột này
1940        chứa một hình thu nhỏ của ảnh sẵn sàng để đọc.
1941    </dd>
1942    <dt>
1943        {@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID}
1944    </dt>
1945    <dd>
1946        Một mã định danh dạng số của ảnh cho một liên lạc thô. Nối giá trị này với hằng số
1947        {@link android.provider.ContactsContract.DisplayPhoto#CONTENT_URI DisplayPhoto.CONTENT_URI}
1948        để nhận một URI nội dung trỏ về một tệp ảnh đơn, rồi gọi
1949        {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String)
1950        openAssetFileDescriptor()} để nhận một điều khiển (handle) cho tệp ảnh.
1951    </dd>
1952    <dt>
1953        {@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI}
1954    </dt>
1955    <dd>
1956        Một URI nội dung trỏ trực tiếp tới tệp ảnh cho ảnh được đại diện bởi hàng này.
1957        Gọi {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String)
1958        openAssetFileDescriptor()} bằng URI này để nhận một điều khiển (handle) cho tệp ảnh.
1959    </dd>
1960</dl>
1961<h3 id="SocialStreamTables">Sử dụng các bảng luồng xã hội</h3>
1962<p>
1963    Những bảng này hoạt động giống như các bảng chính khác trong Trình cung cấp Danh bạ, ngoại trừ:
1964</p>
1965    <ul>
1966        <li>
1967            Những bảng này yêu cầu quyền truy cập bổ sung. Để đọc từ chúng, ứng dụng của bạn
1968            phải có quyền {@code android.Manifest.permission#READ_SOCIAL_STREAM}. Để
1969            sửa đổi chúng, ứng dụng của bạn phải có quyền
1970            {@code android.Manifest.permission#WRITE_SOCIAL_STREAM}.
1971        </li>
1972        <li>
1973            Đối với bảng {@code android.provider.ContactsContract.StreamItems}, số hàng
1974            được lưu giữ cho mỗi liên lạc thô sẽ bị giới hạn. Sau khi đạt đến giới hạn này,
1975            Trình cung cấp Danh bạ sẽ tạo khoảng trống cho các hàng mục dòng mới bằng cách tự động xóa
1976            những hàng có
1977            {@code android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP} lâu nhất. Để nhận
1978            giới hạn, hãy phát hành một truy vấn tới URI nội dung
1979            {@code android.provider.ContactsContract.StreamItems#CONTENT_LIMIT_URI}. Bạn có thể để
1980            tất cả các tham đối khác ngoài URI nội dung được đặt về <code>null</code>. Truy vấn
1981            trả về một Con chạy chứa một hàng đơn, với cột đơn
1982            {@code android.provider.ContactsContract.StreamItems#MAX_ITEMS}.
1983        </li>
1984    </ul>
1985
1986<p>
1987    Lớp {@code android.provider.ContactsContract.StreamItems.StreamItemPhotos} định nghĩa một
1988    bảng con {@code android.provider.ContactsContract.StreamItemPhotos} chứa các hàng ảnh
1989    cho một mục dòng đơn.
1990</p>
1991<h3 id="SocialStreamInteraction">Tương tác từ luồng xã hội</h3>
1992<p>
1993    Dữ liệu từ luồng xã hội được quản lý bởi Trình cung cấp Danh bạ, kết hợp với
1994    ứng dụng danh bạ của thiết bị, cung cấp một cách hiệu quả để kết nối hệ thống mạng xã hội của bạn
1995    với các liên lạc hiện tại. Có sẵn những tính năng sau:
1996</p>
1997    <ul>
1998        <li>
1999            Bằng cách đồng bộ dịch vụ mạng xã hội của bạn với Trình cung cấp Danh bạ bằng một trình điều hợp
2000            đồng bộ, bạn có thể truy xuất hoạt động gần đây đối với danh bạ của một người dùng và lưu giữ nó trong
2001            các bảng {@code android.provider.ContactsContract.StreamItems} và
2002            {@code android.provider.ContactsContract.StreamItemPhotos} để sử dụng sau.
2003        </li>
2004        <li>
2005            Bên cạnh việc đồng bộ hoá thường xuyên, bạn có thể kích khởi trình điều hợp đồng bộ của mình để truy xuất
2006            dữ liệu bổ sung khi người dùng chọn một liên lạc để xem. Điều này cho phép trình điều hợp đồng bộ của bạn
2007            truy xuất ảnh độ phân giải cao và các mục dòng gần đây nhất cho liên lạc đó.
2008        </li>
2009        <li>
2010            Bằng cách đăng ký một thông báo với ứng dụng danh bạ của thiết bị và Trình cung cấp
2011            Danh bạ, bạn có thể <em>nhận</em> một ý định khi một liên lạc được xem, và tại thời điểm đó,
2012            cập nhật trạng thái của liên lạc đó từ dịch vụ của bạn. Phương pháp này có thể nhanh hơn và sử dụng ít
2013            băng thông hơn việc thực hiện đồng bộ đầy đủ với một trình điều hợp đồng bộ.
2014        </li>
2015        <li>
2016            Người dùng có thể thêm một liên lạc vào dịch vụ mạng xã hội của mình trong khi đang xem liên lạc đó
2017            trong ứng dụng danh bạ của thiết bị. Bạn kích hoạt điều này bằng tính năng "mời liên lạc",
2018           theo đó cho phép kết hợp một hoạt động để thêm một liên lạc hiện có vào mạng
2019            của bạn, và một tệp XML để cung cấp cho ứng dụng danh bạ của thiết bị và
2020            Trình cung cấp Danh bạ thông tin chi tiết về ứng dụng của bạn.
2021        </li>
2022    </ul>
2023<p>
2024    Đồng bộ hóa thường xuyên các mục dòng với Trình cung cấp Danh bạ giống như
2025    các trường hợp đồng bộ hoá khác. Để tìm hiểu thêm về đồng bộ hoá, hãy xem phần
2026    <a href="#SyncAdapters">Trình điều hợp Đồng bộ Trình cung cấp Danh bạ</a>. Việc đăng ký thông tin và
2027    mời liên lạc được đề cập trong hai phần tiếp theo.
2028</p>
2029<h4>Đăng ký để xử lý các lượt xem mạng xã hội</h4>
2030<p>
2031    Để đăng ký để trình điều hợp đồng bộ của bạn nhận thông báo khi người dùng xem một liên lạc do
2032    trình điều hợp đồng bộ của bạn quản lý:
2033</p>
2034<ol>
2035    <li>
2036        Tạo một tệp có tên <code>contacts.xml</code> trong thư mục <code>res/xml/</code>
2037        của dự án của bạn. Nếu đã có tệp này, bạn có thể bỏ qua bước này.
2038    </li>
2039    <li>
2040        Trong tệp này, hãy thêm phần tử
2041<code>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</code>.
2042        Nếu phần tử này đã tồn tại, bạn có thể bỏ qua bước này.
2043    </li>
2044    <li>
2045        Để đăng ký một dịch vụ được thông báo khi người dùng mở trang chi tiết của một liên lạc trong
2046        ứng dụng danh bạ của thiết bị, hãy thêm thuộc tính
2047        <code>viewContactNotifyService="<em>serviceclass</em>"</code> vào phần tử, trong đó
2048        <code><em>serviceclass</em></code> là tên lớp được đáp ứng đầy đủ của dịch vụ
2049        mà sẽ nhận ý định từ ứng dụng danh bạ của thiết bị. Đối với dịch vụ
2050        trình thông báo, hãy sử dụng một lớp mở rộng {@link android.app.IntentService}, để cho phép dịch vụ
2051        nhận các ý định. Dữ liệu trong ý định đến chứa URI nội dung của liên lạc
2052        thô mà người dùng đã nhấp vào. Từ dịch vụ trình thông báo, bạn có thể gắn kết với rồi gọi trình điều hợp đồng bộ
2053        của bạn để cập nhật dữ liệu cho liên lạc thô.
2054    </li>
2055</ol>
2056<p>
2057    Để đăng ký một hoạt động sẽ được gọi khi người dùng nhấp vào một mục dòng hay ảnh hoặc cả hai:
2058</p>
2059<ol>
2060    <li>
2061        Tạo một tệp có tên <code>contacts.xml</code> trong thư mục <code>res/xml/</code>
2062        của dự án của bạn. Nếu đã có tệp này, bạn có thể bỏ qua bước này.
2063    </li>
2064    <li>
2065        Trong tệp này, hãy thêm phần tử
2066<code>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</code>.
2067        Nếu phần tử này đã tồn tại, bạn có thể bỏ qua bước này.
2068    </li>
2069    <li>
2070        Để đăng ký một trong các hoạt động của bạn sẽ xử lý khi người dùng nhấp vào một mục dòng trong
2071        ứng dụng danh bạ của thiết bị, hãy thêm thuộc tính
2072        <code>viewStreamItemActivity="<em>activityclass</em>"</code> vào phần tử đó, trong đó
2073        <code><em>activityclass</em></code> là tên lớp được xác định đầy đủ của hoạt động
2074        mà sẽ nhận ý định từ ứng dụng danh bạ của thiết bị.
2075    </li>
2076    <li>
2077        Để đăng ký một trong các hoạt động của bạn sẽ xử lý khi người dùng nhấp vào một ảnh luồng trong
2078        ứng dụng danh bạ của thiết bị, hãy thêm thuộc tính
2079        <code>viewStreamItemPhotoActivity="<em>activityclass</em>"</code> vào phần tử đó, trong đó
2080        <code><em>activityclass</em></code> là tên lớp được xác định đầy đủ của hoạt động
2081        mà sẽ nhận ý định từ ứng dụng danh bạ của thiết bị.
2082    </li>
2083</ol>
2084<p>
2085    Phần tử <code>&lt;ContactsAccountType&gt;</code> được mô tả chi tiết hơn trong mục
2086    phần tử <a href="#SocialStreamAcctType">&lt;ContactsAccountType&gt;</a>.
2087</p>
2088<p>
2089    Ý định đến chứa URI nội dung của mục hoặc ảnh mà người dùng đã nhấp vào.
2090    Để có các hoạt động riêng cho các mục văn bản và ảnh, hãy sử dụng cả hai thuộc tính trong cùng tệp.
2091</p>
2092<h4>Tương tác với dịch vụ mạng xã hội của bạn</h4>
2093<p>
2094    Người dùng không phải rời ứng dụng danh bạ của thiết bị để mời một liên lạc tới trang mạng xã hội
2095    của bạn. Thay vào đó, bạn có thể thiết đặt để ứng dụng danh bạ của thiết bị gửi một ý định để mời
2096    liên lạc đó tới một trong các hoạt động của mình. Để thiết đặt điều này:
2097</p>
2098<ol>
2099    <li>
2100        Tạo một tệp có tên <code>contacts.xml</code> trong thư mục <code>res/xml/</code>
2101        của dự án của bạn. Nếu đã có tệp này, bạn có thể bỏ qua bước này.
2102    </li>
2103    <li>
2104        Trong tệp này, hãy thêm phần tử
2105<code>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</code>.
2106        Nếu phần tử này đã tồn tại, bạn có thể bỏ qua bước này.
2107    </li>
2108    <li>
2109        Thêm các thuộc tính sau:
2110        <ul>
2111            <li><code>inviteContactActivity="<em>activityclass</em>"</code></li>
2112            <li>
2113                <code>inviteContactActionLabel="&#64;string/<em>invite_action_label</em>"</code>
2114            </li>
2115        </ul>
2116        Giá trị <code><em>activityclass</em></code> là tên lớp được xác định đầy đủ của hoạt động
2117        mà sẽ nhận được ý định. Giá trị <code><em>invite_action_label</em></code>
2118        là một xâu văn bản được hiển thị trong menu <strong>Thêm Kết nối</strong> trong ứng dụng danh bạ
2119        của thiết bị.
2120    </li>
2121</ol>
2122<p class="note">
2123    <strong>Lưu ý:</strong> <code>ContactsSource</code> là một tên tag không được chấp nhận đối với
2124    <code>ContactsAccountType</code>.
2125</p>
2126<h3 id="ContactsFile">Tham chiếu contacts.xml</h3>
2127<p>
2128    Tệp <code>contacts.xml</code> chứa các phần tử XML có chức năng kiểm soát tương tác giữa
2129    trình điều hợp đồng bộ và ứng dụng của bạn với ứng dụng danh bạ và Trình cung cấp Danh bạ. Những
2130    phần tử này được mô tả trong các mục sau.
2131</p>
2132<h4 id="SocialStreamAcctType">Thành phần &lt;ContactsAccountType&gt;</h4>
2133<p>
2134    Phần tử <code>&lt;ContactsAccountType&gt;</code> kiểm soát tương tác giữa
2135    ứng dụng của bạn với ứng dụng danh bạ. Nó có những cú pháp sau:
2136</p>
2137<pre>
2138&lt;ContactsAccountType
2139        xmlns:android="http://schemas.android.com/apk/res/android"
2140        inviteContactActivity="<em>activity_name</em>"
2141        inviteContactActionLabel="<em>invite_command_text</em>"
2142        viewContactNotifyService="<em>view_notify_service</em>"
2143        viewGroupActivity="<em>group_view_activity</em>"
2144        viewGroupActionLabel="<em>group_action_text</em>"
2145        viewStreamItemActivity="<em>viewstream_activity_name</em>"
2146        viewStreamItemPhotoActivity="<em>viewphotostream_activity_name</em>"&gt;
2147</pre>
2148<p>
2149    <strong>chứa trong:</strong>
2150</p>
2151<p>
2152    <code>res/xml/contacts.xml</code>
2153</p>
2154<p>
2155    <strong>có thể chứa:</strong>
2156</p>
2157<p>
2158    <strong><code>&lt;ContactsDataKind&gt;</code></strong>
2159</p>
2160<p>
2161    <strong>Mô tả:</strong>
2162</p>
2163<p>
2164    Khai báo các thành phần Android và nhãn UI mà cho phép người dùng mời một trong các liên lạc của mình đến
2165    một mạng xã hội, thông báo người dùng khi một trong các luồng mạng xã hội của họ được cập nhật,
2166    v.v.
2167</p>
2168<p>
2169    Để ý rằng tiền tố thuộc tính <code>android:</code> không nhất thiết áp dụng cho các thuộc tính
2170    của <code>&lt;ContactsAccountType&gt;</code>.
2171</p>
2172<p>
2173    <strong>Thuộc tính:</strong>
2174</p>
2175<dl>
2176    <dt>{@code inviteContactActivity}</dt>
2177    <dd>
2178        Tên lớp được xác định đầy đủ của hoạt động trong ứng dụng của bạn mà bạn muốn
2179        kích hoạt khi người dùng chọn <strong>Thêm kết nối</strong> từ ứng dụng danh bạ
2180        của thiết bị.
2181    </dd>
2182    <dt>{@code inviteContactActionLabel}</dt>
2183    <dd>
2184        Một xâu văn bản được hiển thị cho hoạt động được quy định trong
2185        {@code inviteContactActivity}, trong menu <strong>Thêm kết nối</strong>.
2186        Ví dụ, bạn có thể sử dụng xâu "Follow in my network". Bạn có thể sử dụng mã định danh
2187        tài nguyên xâu cho nhãn này.
2188    </dd>
2189    <dt>{@code viewContactNotifyService}</dt>
2190    <dd>
2191        Tên lớp được xác định đầy đủ của một dịch vụ trong ứng dụng của bạn mà sẽ nhận được
2192        thông báo khi người dùng xem một liên lạc. Thông báo này được gửi từ ứng dụng danh bạ
2193        của thiết bị; nó cho phép ứng dụng của bạn tạm hoãn các thao tác dùng nhiều dữ liệu tới
2194        khi cần. Ví dụ, ứng dụng của bạn có thể hồi đáp lại thông báo này
2195        bằng cách đọc và hiển thị ảnh độ phân giải cao của danh bạ và các mục dòng mạng xã hội
2196        gần đây nhất. Tính năng này được mô tả chi tiết hơn trong phần
2197        <a href="#SocialStreamInteraction">Tương tác với luồng xã hội</a>. Bạn có thể thấy một
2198        ví dụ về dịch vụ thông báo trong tệp <code>NotifierService.java</code> trong ứng dụng mẫu
2199        <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">SampleSyncAdapter</a>
2200.
2201    </dd>
2202    <dt>{@code viewGroupActivity}</dt>
2203    <dd>
2204        Tên lớp được xác định đầy đủ của một hoạt động trong ứng dụng của bạn mà có thể
2205        hiển thị thông tin nhóm. Khi người dùng nhấp vào nhãn nhóm trong ứng dụng danh bạ
2206        của thiết bị, UI cho hoạt động này sẽ được hiển thị.
2207    </dd>
2208    <dt>{@code viewGroupActionLabel}</dt>
2209    <dd>
2210        Nhãn mà ứng dụng danh bạ hiển thị cho một điều khiển UI có cho phép
2211        người dùng xem các nhóm trong ứng dụng của bạn.
2212        <p>
2213            Ví dụ, nếu bạn cài đặt ứng dụng Google+ trên thiết bị của mình và bạn đồng bộ
2214            Google+ với ứng dụng danh bạ, bạn sẽ thấy các vòng tròn Google+ được liệt kê thành các nhóm
2215            trong tab <strong>Nhóm</strong> của ứng dụng danh bạ của bạn. Nếu bạn nhấp vào một vòng tròn
2216            Google+, bạn sẽ thấy những người trong vòng tròn đó được liệt kê thành một "nhóm". Phía bên trên của
2217            hiển thị, bạn sẽ thấy một biểu tượng Google+; nếu bạn nhấp vào đó, điều khiển sẽ chuyển sang ứng dụng
2218            Google+. Ứng dụng danh bạ làm điều này bằng
2219            {@code viewGroupActivity}, bằng cách sử dụng biểu tượng Google+ làm giá trị của
2220            {@code viewGroupActionLabel}.
2221        </p>
2222        <p>
2223            Một mã định danh tài nguyên xâu được cho phép cho thuộc tính này.
2224        </p>
2225    </dd>
2226    <dt>{@code viewStreamItemActivity}</dt>
2227    <dd>
2228        Tên lớp được xác định đầy đủ của một hoạt động trong ứng dụng của bạn mà
2229        ứng dụng danh bạ của thiết bị khởi chạy khi người dùng nhấp vào một mục dòng đối với một liên lạc thô.
2230    </dd>
2231    <dt>{@code viewStreamItemPhotoActivity}</dt>
2232    <dd>
2233        Tên lớp được xác định đầy đủ của một hoạt động trong ứng dụng của bạn mà
2234       ứng dụng danh bạ của thiết bị khởi chạy khi người dùng nhấp vào một ảnh trong mục dòng
2235        đối với một liên lạc thô.
2236    </dd>
2237</dl>
2238<h4 id="SocialStreamDataKind">Phần tử &lt;ContactsDataKind&gt;</h4>
2239<p>
2240    Phần tử <code>&lt;ContactsDataKind&gt;</code> kiểm soát việc hiển thị các hàng
2241    dữ liệu tùy chỉnh của ứng dụng của bạn trong UI của ứng dụng danh bạ. Nó có những cú pháp sau:
2242</p>
2243<pre>
2244&lt;ContactsDataKind
2245        android:mimeType="<em>MIMEtype</em>"
2246        android:icon="<em>icon_resources</em>"
2247        android:summaryColumn="<em>column_name</em>"
2248        android:detailColumn="<em>column_name</em>"&gt;
2249</pre>
2250<p>
2251    <strong>chứa trong:</strong>
2252</p>
2253<code>&lt;ContactsAccountType&gt;</code>
2254<p>
2255    <strong>Mô tả:</strong>
2256</p>
2257<p>
2258    Sử dụng phần tử này để ứng dụng danh bạ hiển thị các nội dung trong một hàng dữ liệu tùy chỉnh như
2259    một phần chi tiết của một liên lạc thô. Mỗi phần tử con <code>&lt;ContactsDataKind&gt;</code>
2260    của <code>&lt;ContactsAccountType&gt;</code> đại diện cho một kiểu hàng dữ liệu tùy chỉnh mà trình điều hợp
2261    đồng bộ của bạn thêm vào bảng {@link android.provider.ContactsContract.Data}. Thêm một phần tử
2262    <code>&lt;ContactsDataKind&gt;</code> cho mỗi kiểu MIME tùy chỉnh mà bạn sử dụng. Bạn không phải
2263    thêm phần tử nếu có một hàng dữ liệu tùy chỉnh mà bạn không muốn hiển thị dữ liệu.
2264</p>
2265<p>
2266    <strong>Thuộc tính:</strong>
2267</p>
2268<dl>
2269    <dt>{@code android:mimeType}</dt>
2270    <dd>
2271        Kiểu MIME tùy chỉnh mà bạn đã định nghĩa cho một trong các kiểu hàng dữ liệu tùy chỉnh của bạn trong bảng
2272        {@link android.provider.ContactsContract.Data}. Ví dụ, giá trị
2273        <code>vnd.android.cursor.item/vnd.example.locationstatus</code> có thể là một kiểu
2274        MIME tùy chỉnh cho một hàng dữ liệu có chức năng ghi lại vị trí được biết đến cuối cùng của một liên lạc.
2275    </dd>
2276    <dt>{@code android:icon}</dt>
2277    <dd>
2278        Một tài nguyên
2279        <a href="{@docRoot}guide/topics/resources/drawable-resource.html">có thể vẽ của Android</a>
2280        mà ứng dụng danh bạ hiển thị bên cạnh dữ liệu của bạn. Sử dụng nó để thể hiện với
2281        người dùng rằng dữ liệu xuất phát từ dịch vụ của bạn.
2282    </dd>
2283    <dt>{@code android:summaryColumn}</dt>
2284    <dd>
2285        Tên cột của giá trị thứ nhất trong hai giá trị được truy xuất từ hàng dữ liệu. Giá trị
2286        được hiển thị là dòng thứ nhất của mục nhập cho hàng dữ liệu này. Dòng thứ nhất có
2287        mục đích sử dụng làm bản tóm tắt dữ liệu, nhưng điều đó là tùy chọn. Xem thêm
2288        <a href="#detailColumn">android:detailColumn</a>.
2289    </dd>
2290    <dt>{@code android:detailColumn}</dt>
2291    <dd>
2292        Tên cột của giá trị thứ hai trong hai giá trị được truy xuất từ hàng dữ liệu. Giá trị
2293        được hiển thị là dòng thứ hai của mục nhập cho hàng dữ liệu này. Xem thêm
2294        {@code android:summaryColumn}.
2295    </dd>
2296</dl>
2297<h2 id="AdditionalFeatures">Các Tính năng Bổ sung của Trình cung cấp Danh bạ</h2>
2298<p>
2299    Bên cạnh các tính năng chính được mô tả trong các phần trước, Trình cung cấp Danh bạ còn cung cấp
2300    những tính năng hữu ích sau khi làm việc với dữ liệu danh bạ:
2301</p>
2302    <ul>
2303       <li>Nhóm liên lạc</li>
2304       <li>Tính năng ảnh</li>
2305    </ul>
2306<h3 id="Groups">Nhóm liên lạc</h3>
2307<p>
2308    Trình cung cấp Danh bạ có thể tùy chọn đánh nhãn các bộ sưu tập liên lạc có liên quan bằng dữ liệu
2309    <strong>nhóm</strong>. Nếu máy chủ liên kết với một tài khoản người dùng
2310    muốn duy trì nhóm, trình điều hợp đồng bộ cho loại tài khoản của tài khoản đó sẽ chuyển
2311    dữ liệu nhóm giữa Trình cung cấp Danh bạ và máy chủ. Khi người dùng thêm một liên lạc mới vào
2312    máy chủ, trình điều hợp đồng bộ phải thêm nhóm mới
2313    vào bảng {@link android.provider.ContactsContract.Groups}. Nhóm hoặc các nhóm mà một liên lạc
2314    thô thuộc về được lưu giữ trong bảng {@link android.provider.ContactsContract.Data}, bằng cách sử dụng
2315    kiểu MIME {@link android.provider.ContactsContract.CommonDataKinds.GroupMembership}.
2316</p>
2317<p>
2318    Nếu bạn đang thiết kế một trình điều hợp đồng bộ mà sẽ thêm dữ liệu liên lạc thô từ
2319    máy chủ tới Trình cung cấp Danh bạ, và bạn không sử dụng các nhóm, khi đó bạn cần báo cho
2320    Trình cung cấp làm các dữ liệu của bạn thấy được. Trong đoạn mã được thực hiện khi một người dùng thêm một tài khoản
2321    vào thiết bị, hãy cập nhật hàng {@link android.provider.ContactsContract.Settings}
2322    mà Trình cung cấp Danh bạ thêm cho tài khoản. Trong hàng này, đặt giá trị của cột
2323    {@link android.provider.ContactsContract.SettingsColumns#UNGROUPED_VISIBLE
2324    Settings.UNGROUPED_VISIBLE} thành 1. Khi bạn làm vậy, Trình cung cấp Danh bạ sẽ luôn
2325    làm cho dữ liệu danh bạ của bạn thấy được, ngay cả khi bạn không sử dụng nhóm.
2326</p>
2327<h3 id="Photos">Ảnh liên lạc</h3>
2328<p>
2329    Bảng {@link android.provider.ContactsContract.Data} lưu giữ ảnh thành hàng với kiểu MIME
2330    {@link android.provider.ContactsContract.CommonDataKinds.Photo#CONTENT_ITEM_TYPE
2331    Photo.CONTENT_ITEM_TYPE}. Cột
2332    {@link android.provider.ContactsContract.RawContactsColumns#CONTACT_ID} của hàng được liên kết với cột
2333    {@code android.provider.BaseColumns#_ID} của liên lạc thô mà nó thuộc về.
2334    Lớp {@link android.provider.ContactsContract.Contacts.Photo} định nghĩa một bảng con của
2335    {@link android.provider.ContactsContract.Contacts} chứa thông tin ảnh về ảnh chính
2336    của một liên lạc, đây là ảnh chính của liên lạc thô chính của liên lạc. Tương tự,
2337    lớp {@link android.provider.ContactsContract.RawContacts.DisplayPhoto} định nghĩa một bảng con
2338    của {@link android.provider.ContactsContract.RawContacts} chứa thông tin ảnh đối với ảnh chính
2339    của một liên lạc thô.
2340</p>
2341<p>
2342    Tài liệu tham khảo cho {@link android.provider.ContactsContract.Contacts.Photo} và
2343    {@link android.provider.ContactsContract.RawContacts.DisplayPhoto} có các ví dụ về
2344    việc truy xuất thông tin ảnh. Không có lớp thuận tiện cho việc truy xuất hình thu nhỏ
2345    chính đối với một liên lạc thô, nhưng bạn có thể gửi một truy vấn tới bảng
2346    {@link android.provider.ContactsContract.Data}, chọn
2347    {@code android.provider.BaseColumns#_ID} của liên lạc thô,
2348    {@link android.provider.ContactsContract.CommonDataKinds.Photo#CONTENT_ITEM_TYPE
2349    Photo.CONTENT_ITEM_TYPE}, và cột {@link android.provider.ContactsContract.Data#IS_PRIMARY}
2350    để tìm hàng ảnh chính của liên lạc thô.
2351</p>
2352<p>
2353    Dữ liệu từ luồng xã hội đối với một người cũng có thể bao gồm ảnh. Những ảnh này được lưu giữ trong bảng
2354    {@code android.provider.ContactsContract.StreamItemPhotos}, được mô tả chi tiết hơn
2355    trong phần <a href="#StreamPhotos">Ảnh từ luồng xã hội</a>.
2356</p>
2357