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 <uses-permission></a></code> là 569 <code><uses-permission android:name="android.permission.READ_CONTACTS"></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 <uses-permission></a></code> là 577 <code><uses-permission android:name="android.permission.WRITE_CONTACTS"></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@Override 886public Loader<Cursor> 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<ContentProviderOperation> ops = 1070 new ArrayList<ContentProviderOperation>(); 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<Cursor> 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<ContentProviderOperationg>; 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<ContentValues> contactData = new ArrayList<ContentValues>(); 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><ContactsAccountType></code> và một hoặc nhiều phần tử con 1621 <code><ContactsDataKind></code> của nó. Điều này được mô tả chi tiết hơn trong 1622 phần <a href="#SocialStreamDataKind"><code><ContactsDataKind> 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><<a href="{@docRoot}guide/topics/manifest/service-element.html">service</a>></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><<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>></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><<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>></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><<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>></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><ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"></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><ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"></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><ContactsAccountType></code> được mô tả chi tiết hơn trong mục 2086 phần tử <a href="#SocialStreamAcctType"><ContactsAccountType></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><ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"></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="@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 <ContactsAccountType></h4> 2133<p> 2134 Phần tử <code><ContactsAccountType></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<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>"> 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><ContactsDataKind></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><ContactsAccountType></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ử <ContactsDataKind></h4> 2239<p> 2240 Phần tử <code><ContactsDataKind></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<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>"> 2249</pre> 2250<p> 2251 <strong>chứa trong:</strong> 2252</p> 2253<code><ContactsAccountType></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><ContactsDataKind></code> 2260 của <code><ContactsAccountType></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><ContactsDataKind></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