1 page.title=Penyedia Kontak 2 @jd:body 3 <div id="qv-wrapper"> 4 <div id="qv"> 5 <h2>Tampilan Cepat</h2> 6 <ul> 7 <li>Repository informasi Android tentang orang.</li> 8 <li> 9 Sinkronisasi dengan web. 10 </li> 11 <li> 12 Mengintegrasikan data aliran sosial. 13 </li> 14 </ul> 15 <h2>Dalam dokumen ini</h2> 16 <ol> 17 <li> 18 <a href="#InformationTypes">Organisasi Penyedia Kontak</a> 19 </li> 20 <li> 21 <a href="#RawContactBasics">Kontak mentah</a> 22 </li> 23 <li> 24 <a href="#DataBasics">Data</a> 25 </li> 26 <li> 27 <a href="#ContactBasics">Kontak</a> 28 </li> 29 <li> 30 <a href="#Sources">Data Dari Adaptor Sinkronisasi</a> 31 </li> 32 <li> 33 <a href="#Permissions">Izin yang Diperlukan</a> 34 </li> 35 <li> 36 <a href="#UserProfile">Profil Pengguna</a> 37 </li> 38 <li> 39 <a href="#ContactsProviderMetadata">Metadata Penyedia Kontak</a> 40 </li> 41 <li> 42 <a href="#Access">Akses Penyedia Kontak</a> 43 <li> 44 </li> 45 <li> 46 <a href="#SyncAdapters">Adaptor Sinkronisasi Penyedia Kontak</a> 47 </li> 48 <li> 49 <a href="#SocialStream">Data Aliran Sosial</a> 50 </li> 51 <li> 52 <a href="#AdditionalFeatures">Fitur Tambahan Penyedia Kontak</a> 53 </li> 54 </ol> 55 <h2>Kelas-kelas utama</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>Contoh-Contoh Terkait</h2> 63 <ol> 64 <li> 65 <a href="{@docRoot}resources/samples/ContactManager/index.html"> 66 Contact Manager 67 </a> 68 </li> 69 <li> 70 <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html"> 71 Contoh Adaptor Sinkronisasi</a> 72 </li> 73 </ol> 74 <h2>Lihat Juga</h2> 75 <ol> 76 <li> 77 <a href="{@docRoot}guide/topics/providers/content-provider-basics.html"> 78 Dasar-Dasar Penyedia Konten 79 </a> 80 </li> 81 </ol> 82 </div> 83 </div> 84 <p> 85 Penyedia Kontak adalah komponen Android yang tangguh dan fleksibel dalam mengelola 86 repository data pusat tentang orang di perangkat. Penyedia Kontak adalah sumber data 87 yang Anda lihat dalam aplikasi kontak perangkat, dan Anda juga bisa mengakses datanya dalam aplikasi 88 Anda sendiri serta mentransfer data antara perangkat dan layanan online. Penyedia mengakomodasi 89 berbagai sumber data dan mencoba mengelola data sebanyak mungkin untuk setiap orang, sehingga 90 organisasinya menjadi kompleks. Karena itu, API penyedia menyertakan 91 satu set kelas kontrak dan antarmuka ekstensif yang membantu pengambilan dan 92 modifikasi data. 93 </p> 94 <p> 95 Panduan ini menjelaskan hal-hal berikut: 96 </p> 97 <ul> 98 <li> 99 Struktur penyedia dasar. 100 </li> 101 <li> 102 Cara mengambil data dari penyedia. 103 </li> 104 <li> 105 Cara memodifikasi data di penyedia. 106 </li> 107 <li> 108 Cara menulis adaptor sinkronisasi untuk menyinkronkan data dari server Anda ke 109 Penyedia Kontak. 110 </li> 111 </ul> 112 <p> 113 Panduan ini beranggapan bahwa Anda mengetahui dasar-dasar penyedia konten Android. Untuk mengetahui selengkapnya 114 tentang penyedia konten Android, bacalah 115 panduan<a href="{@docRoot}guide/topics/providers/content-provider-basics.html"> 116 Dasar-Dasar Penyedia Konten</a>. Contoh aplikasi 117 <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">Sample Sync Adapter</a> 118 adalah contoh penggunaan adaptor sinkronisasi untuk mentransfer data antara Penyedia Kontak 119 dan contoh aplikasi yang memiliki host di Google Web Services. 120 </p> 121 <h2 id="InformationTypes">Organisasi Penyedia Kontak</h2> 122 <p> 123 Penyedia Kontak adalah komponen penyedia konten Android. Komponen ini memelihara tiga tipe 124 data tentang seseorang, masing-masing disesuaikan dengan tabel yang ditawarkan oleh penyedia, seperti 125 yang terlihat dalam gambar 1: 126 </p> 127 <img src="{@docRoot}images/providers/contacts_structure.png" alt="" height="364" id="figure1" /> 128 <p class="img-caption"> 129 <strong>Gambar 1.</strong> Struktur tabel Penyedia Kontak. 130 </p> 131 <p> 132 Ketiga tabel disebut secara umum menurut nama kelas kontrak. Kelas 133 mendefinisikan konstanta untuk URI konten, nama kolom, dan nilai kolom yang digunakan oleh tabel-tabel: 134 </p> 135 <dl> 136 <dt> 137 Tabel {@link android.provider.ContactsContract.Contacts} 138 </dt> 139 <dd> 140 Baris mewakili orang yang berbeda, berdasarkan agregrasi baris kontak mentah. 141 </dd> 142 <dt> 143 Tabel {@link android.provider.ContactsContract.RawContacts} 144 </dt> 145 <dd> 146 Baris berisi rangkuman data seseorang, untuk tipe dan akun pengguna tertentu. 147 </dd> 148 <dt> 149 Tabel {@link android.provider.ContactsContract.Data} 150 </dt> 151 <dd> 152 Baris berisi data untuk kontak mentah, seperti alamat email atau nomor telepon. 153 </dd> 154 </dl> 155 <p> 156 Tabel lain yang diwakili oleh kelas kontrak dalam {@link android.provider.ContactsContract} 157 adalah tabel tambahan yang digunakan Penyedia Kontak untuk mengelola operasinya atau mendukung 158 fungsi tertentu dalam kontak atau aplikasi telepon perangkat. 159 </p> 160 <h2 id="RawContactBasics">Kontak mentah</h2> 161 <p> 162 Kontak mentah mewakili data seseorang yang berasal dari satu tipe akun dan nama 163 akun. Karena Penyedia Kontak memungkinkan lebih dari satu layanan online sebagai sumber 164 data untuk satu orang, Penyedia Kontak memungkinkan multikontak mentah untuk orang yang sama. 165 Multikontak mentah juga memungkinkan seorang pengguna mengombinasikan data seseorang dari lebih dari satu akun 166 bertipe akun yang sama. 167 </p> 168 <p> 169 Sebagian besar data untuk kontak mentah tidak disimpan dalam 170 tabel {@link android.provider.ContactsContract.RawContacts}. Sebagai gantinya, data tersebut disimpan dalam satu atau beberapa baris 171 dalam tabel {@link android.provider.ContactsContract.Data}. Setiap baris data memiliki kolom 172 {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID Data.RAW_CONTACT_ID} yang 173 berisi nilai {@code android.provider.BaseColumns#_ID RawContacts._ID} dari 174 baris {@link android.provider.ContactsContract.RawContacts} induknya. 175 </p> 176 <h3 id="RawContactsColumns">Kolom-kolom kontak mentah yang penting</h3> 177 <p> 178 Kolom-kolom penting dalam tabel {@link android.provider.ContactsContract.RawContacts} 179 tercantum pada tabel 1. Bacalah catatan yang diberikan setelah tabel: 180 </p> 181 <p class="table-caption" id="table1"> 182 <strong>Tabel 1.</strong> Kolom-kolom kontak mentah yang penting. 183 </p> 184 <table> 185 <tr> 186 <th scope="col">Nama kolom</th> 187 <th scope="col">Kegunaan</th> 188 <th scope="col">Catatan</th> 189 </tr> 190 <tr> 191 <td> 192 {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_NAME} 193 </td> 194 <td> 195 Nama akun untuk tipe akun yang merupakan sumber kontak mentah ini. 196 Misalnya, nama akun dari akun Google adalah salah satu alamat Gmail 197 pemilik perangkat. Lihat entri berikutnya untuk 198 {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_TYPE} untuk informasi 199 selengkapnya. 200 </td> 201 <td> 202 Format nama ini khusus untuk tipe akun ini. Format ini tidak 203 harus alamat email. 204 </td> 205 </tr> 206 <tr> 207 <td> 208 {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_TYPE} 209 </td> 210 <td> 211 Tipe akun yang merupakan sumber kontak mentah ini. Misalnya, tipe 212 akun dari akun Google adalah <code>com.google</code>. Selalu batasi tipe akun Anda 213 dengan identifier domain untuk domain yang Anda miliki atau kontrol. Hal ini akan memastikan bahwa tipe 214 akun Anda bersifat unik. 215 </td> 216 <td> 217 Tipe akun yang menawarkan data kontak biasanya memiliki adaptor sinkronisasi terkait yang 218 menyinkronkan dengan Penyedia Kontak. 219 </tr> 220 <tr> 221 <td> 222 {@link android.provider.ContactsContract.RawContactsColumns#DELETED} 223 </td> 224 <td> 225 Flag "deleted" untuk kontak mentah. 226 </td> 227 <td> 228 Flag ini memungkinkan Penyedia Kontak memelihara baris secara internal hingga adaptor 229 sinkronisasi bisa menghapus baris dari server mereka dan akhirnya menghapus baris 230 dari repository. 231 </td> 232 </tr> 233 </table> 234 <h4>Catatan</h4> 235 <p> 236 Berikut ini adalah catatan penting tentang 237 tabel {@link android.provider.ContactsContract.RawContacts}: 238 </p> 239 <ul> 240 <li> 241 Nama kontak mentah tidak disimpan di barisnya dalam 242 {@link android.provider.ContactsContract.RawContacts}. Sebagai gantinya, nama tersebut disimpan dalam 243 tabel {@link android.provider.ContactsContract.Data}, pada 244 baris {@link android.provider.ContactsContract.CommonDataKinds.StructuredName}. Kontak mentah 245 hanya memiliki satu baris dari tipe ini dalam tabel {@link android.provider.ContactsContract.Data}. 246 </li> 247 <li> 248 <strong>Perhatian:</strong> Untuk menggunakan data akun sendiri dalam baris kontak mentah, akun harus 249 didaftarkan lebih dahulu dengan {@link android.accounts.AccountManager}. Caranya, mintalah 250 pengguna untuk menambahkan tipe akun dan nama akun ke dalam daftar akun. Jika Anda tidak 251 melakukannya, Penyedia Kontak secara otomatis akan menghapus baris kontak mentah Anda. 252 <p> 253 Misalnya, Anda menginginkan aplikasi memelihara data kontak untuk layanan berbasis web 254 dengan domain {@code com.example.dataservice}, dan akun pengguna untuk layanan Anda 255 adalah {@code becky.sharp (a] dataservice.example.com}, pengguna harus menambahkan lebih dahulu "type" 256 akun ({@code com.example.dataservice}) dan "name" akun 257 ({@code becky.smart (a] dataservice.example.com}) sebelum aplikasi Anda bisa menambahkan baris kontak mentah. 258 Anda bisa menjelaskan ketentuan ini kepada pengguna dalam dokumentasi, atau meminta 259 pengguna untuk menambahkan tipe dan nama, atau keduanya. Tipe akun dan nama akun 260 dijelaskan lebih detail di bagian berikutnya. 261 </li> 262 </ul> 263 <h3 id="RawContactsExample">Sumber data kontak mentah</h3> 264 <p> 265 Untuk memahami cara kerja kontak mentah, perhatikan pengguna "Emily Dickinson" yang mendefinisikan 266 tiga akun pengguna berikut pada perangkatnya: 267 </p> 268 <ul> 269 <li><code>emily.dickinson (a] gmail.com</code></li> 270 <li><code>emilyd (a] gmail.com</code></li> 271 <li>Akun Twitter "belle_of_amherst"</li> 272 </ul> 273 <p> 274 Pengguna ini telah mengaktifkan <em>Sync Contacts</em> untuk ketiga akun dalam pengaturan 275 <em>Accounts</em>. 276 </p> 277 <p> 278 Anggaplah Emily Dickinson membuka jendela browser, masuk ke Gmail sebagai 279 <code>emily.dickinson (a] gmail.com</code>, membuka 280 Contacts, dan menambahkan "Thomas Higginson". Kemudian, ia masuk ke Gmail sebagai 281 <code>emilyd (a] gmail.com</code> dan mengirimkan email kepada "Thomas Higginson", yang 282 menambahkan Thomas secara otomatis sebagai kontak. Ia juga mengikuti "colonel_tom" (ID Twitter Thomas Higginson) di 283 Twitter. 284 </p> 285 <p> 286 Penyedia Kontak membuat tiga kontak mentah akibat pekerjaan ini: 287 </p> 288 <ol> 289 <li> 290 Kontak mentah untuk "Thomas Higginson" yang dikaitkan dengan <code>emily.dickinson (a] gmail.com</code>. 291 Tipe akun penggunanya adalah Google. 292 </li> 293 <li> 294 Kontak mentah kedua untuk "Thomas Higginson" yang dikaitkan dengan <code>emilyd (a] gmail.com</code>. 295 Tipe akun pengguna juga Google. Ada kontak mentah kedua 296 meskipun nama tersebut identik dengan nama sebelumnya karena orang bersangkutan ditambahkan untuk 297 akun pengguna yang berbeda. 298 </li> 299 <li> 300 Kontak mentah ketiga untuk "Thomas Higginson" yang dikaitkan dengan "belle_of_amherst". Tipe 301 akun penggunanya adalah Twitter. 302 </li> 303 </ol> 304 <h2 id="DataBasics">Data</h2> 305 <p> 306 Seperti yang telah disebutkan, data untuk kontak mentah disimpan dalam 307 baris {@link android.provider.ContactsContract.Data} yang ditautkan dengan nilai 308 <code>_ID</code> kontak mentah. Cara ini memungkinkan satu kontak mentah memiliki beberapa instance tipe data 309 yang sama dengan alamat email atau nomor telepon. Misalnya, jika 310 "Thomas Higginson" untuk {@code emilyd (a] gmail.com} (baris kontak mentah untuk Thomas Higginson 311 yang dikaitkan dengan akun Google <code>emilyd (a] gmail.com</code>) memiliki alamat email rumah 312 <code>thigg (a] gmail.com</code> dan alamat email kerja 313 <code>thomas.higginson (a] gmail.com</code>, Penyedia Kontak akan menyimpan dua baris alamat 314 email dan menautkan keduanya ke kontak mentah. 315 </p> 316 <p> 317 Perhatikan bahwa tipe data yang berbeda disimpan dalam satu tabel ini. Baris-baris nama tampilan, 318 nomor telepon, email, alamat surat, foto, dan data situs web semuanya bisa ditemukan dalam 319 tabel {@link android.provider.ContactsContract.Data}. Untuk membantu mengelola ini, 320 tabel {@link android.provider.ContactsContract.Data} memiliki beberapa kolom dengan nama deskriptif, 321 dalam kolom lain dengan nama generik. Konten kolom bernama deskriptif memiliki arti yang sama 322 terlepas dari tipe data dalam barisnya, sedangkan konten kolom bernama generik memiliki 323 arti yang berbeda-beda sesuai dengan tipe data. 324 </p> 325 <h3 id="DescriptiveColumns">Nama kolom deskriptif</h3> 326 <p> 327 Beberapa contoh nama kolom deskriptif adalah: 328 </p> 329 <dl> 330 <dt> 331 {@link android.provider.ContactsContract.Data#RAW_CONTACT_ID} 332 </dt> 333 <dd> 334 Nilai kolom <code>_ID</code> kontak mentah untuk data ini. 335 </dd> 336 <dt> 337 {@link android.provider.ContactsContract.Data#MIMETYPE} 338 </dt> 339 <dd> 340 Tipe data yang disimpan dalam baris ini, dinyatakan berupa tipe MIME custom. Penyedia Kontak 341 menggunakan tipe MIME yang didefinisikan dalam subkelas 342 {@link android.provider.ContactsContract.CommonDataKinds}. Tipe MIME ini adalah sumber terbuka, 343 dan bisa digunakan oleh setiap aplikasi atau adaptor sinkronisasi yang bisa digunakan bersama Penyedia Kontak. 344 </dd> 345 <dt> 346 {@link android.provider.ContactsContract.DataColumns#IS_PRIMARY} 347 </dt> 348 <dd> 349 Jika tipe baris data ini bisa terjadi lebih dari satu kali untuk suatu kontak mentah, 350 kolom {@link android.provider.ContactsContract.DataColumns#IS_PRIMARY} 351 menandai baris data yang berisi data utama untuk tipe itu. Misalnya, jika 352 pengguna menekan lama sebuah nomor telepon untuk kontak dan memilih <strong>Set default</strong>, 353 maka baris {@link android.provider.ContactsContract.Data} yang berisi angka itu 354 mengatur kolom {@link android.provider.ContactsContract.DataColumns#IS_PRIMARY}-nya ke suatu 355 nilai bukan nol. 356 </dd> 357 </dl> 358 <h3 id="GenericColumns">Nama kolom generik</h3> 359 <p> 360 Ada 15 kolom generik bernama <code>DATA1</code> hingga 361 <code>DATA15</code> yang tersedia secara umum dan empat kolom generik 362 tambahan <code>SYNC1</code> hingga <code>SYNC4</code> yang harus digunakan hanya oleh adaptor 363 sinkronisasi. Konstanta nama kolom generik selalu berfungsi, terlepas dari tipe 364 data dalam baris . 365 </p> 366 <p> 367 Kolom <code>DATA1</code> diindeks. Penyedia Kontak selalu menggunakan kolom ini untuk 368 data yang diharapkan penyedia akan menjadi target yang paling sering dari suatu query. Misalnya, 369 dalam baris email, kolom ini berisi alamat email sebenarnya. 370 </p> 371 <p> 372 Sesuai konvensi, kolom <code>DATA15</code> dicadangkan untuk menyimpan data Binary Large Object 373 (BLOB) seperti thumbnail foto. 374 </p> 375 <h3 id="TypeSpecificNames">Nama kolom bertipe spesifik</h3> 376 <p> 377 Guna memudahkan pekerjaan dengan kolom untuk tipe baris tertentu, Penyedia Kontak 378 juga menyediakan konstanta nama kolom bertipe spesifik, yang didefinisikan dalam subkelas 379 {@link android.provider.ContactsContract.CommonDataKinds}. Konstanta cuma memberikan nama 380 konstanta yang berbeda ke nama kolom yang sama, yang membantu Anda mengakses data dalam baris 381 bertipe spesifik. 382 </p> 383 <p> 384 Misalnya, kelas {@link android.provider.ContactsContract.CommonDataKinds.Email} mendefinisikan 385 konstanta nama kolom bertipe spesifik untuk baris {@link android.provider.ContactsContract.Data} 386 yang memiliki tipe MIME 387 {@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_ITEM_TYPE 388 Email.CONTENT_ITEM_TYPE}. Kelas ini berisi konstanta 389 {@link android.provider.ContactsContract.CommonDataKinds.Email#ADDRESS} untuk kolom 390 alamat email. Nilai sesungguhnya dari 391 {@link android.provider.ContactsContract.CommonDataKinds.Email#ADDRESS} adalah "data1", yang 392 sama dengan nama generik kolom. 393 </p> 394 <p class="caution"> 395 <strong>Perhatian:</strong> Jangan tambahkan data custom Anda sendiri ke 396 tabel {@link android.provider.ContactsContract.Data} dengan menggunakan baris yang memiliki salah satu 397 tipe MIME yang telah didefinisikan penyedia. Jika melakukannya, Anda bisa kehilangan data atau menyebabkan penyedia 398 gagal berfungsi. Misalnya, Anda seharusnya tidak menambahkan baris bertipe MIME 399 {@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_ITEM_TYPE 400 Email.CONTENT_ITEM_TYPE} yang berisi nama pengguna sebagai ganti alamat email dalam 401 kolom <code>DATA1</code>. Jika Anda menggunakan tipe MIME custom sendiri untuk baris bersangkutan, maka Anda bebas 402 untuk mendefinisikan nama kolom bertipe spesifik dan menggunakan kolom sekehendak Anda. 403 </p> 404 <p> 405 Gambar 2 menampilkan cara kolom deskriptif dan kolom data muncul dalam 406 baris {@link android.provider.ContactsContract.Data}, dan cara nama kolom bertipe spesifik "melapisi" 407 nama kolom generik 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>Gambar 2.</strong> Nama kolom bertipe spesifik dan nama kolom generik. 412 </p> 413 <h3 id="ColumnMaps">Kelas nama kolom bertipe spesifik</h3> 414 <p> 415 Tabel 2 berisi daftar kelas nama kolom bertipe spesifik yang paling umum digunakan: 416 </p> 417 <p class="table-caption" id="table2"> 418 <strong>Tabel 2.</strong> Kelas nama kolom bertipe spesifik</p> 419 <table> 420 <tr> 421 <th scope="col">Kelas pemetaan</th> 422 <th scope="col">Tipe data</th> 423 <th scope="col">Catatan</th> 424 </tr> 425 <tr> 426 <td>{@link android.provider.ContactsContract.CommonDataKinds.StructuredName}</td> 427 <td>Data nama untuk kontak mentah yang dikaitkan dengan baris data ini.</td> 428 <td>Kontak mentah hanya memiliki salah satu baris ini.</td> 429 </tr> 430 <tr> 431 <td>{@link android.provider.ContactsContract.CommonDataKinds.Photo}</td> 432 <td>Foto utama untuk kontak mentah yang dikaitkan dengan baris data ini.</td> 433 <td>Kontak mentah hanya memiliki salah satu baris ini.</td> 434 </tr> 435 <tr> 436 <td>{@link android.provider.ContactsContract.CommonDataKinds.Email}</td> 437 <td>Alamat email untuk kontak mentah yang dikaitkan dengan baris data ini.</td> 438 <td>Kontak mentah bisa memiliki beberapa alamat email.</td> 439 </tr> 440 <tr> 441 <td>{@link android.provider.ContactsContract.CommonDataKinds.StructuredPostal}</td> 442 <td>Alamat pos untuk kontak mentah yang dikaitkan dengan baris data ini.</td> 443 <td>Kontak mentah bisa memiliki beberapa alamat email.</td> 444 </tr> 445 <tr> 446 <td>{@link android.provider.ContactsContract.CommonDataKinds.GroupMembership}</td> 447 <td>Identifier yang menautkan kontak mentah ke salah satu grup dalam Penyedia Kontak.</td> 448 <td> 449 Grup adalah fitur opsional pada tipe akun dan nama akun. Grup dijelaskan 450 lebih detail di bagian <a href="#Groups">Grup kontak</a>. 451 </td> 452 </tr> 453 </table> 454 <h3 id="ContactBasics">Kontak</h3> 455 <p> 456 Penyedia Kontak mengombinasikan baris kontak mentah di semua tipe akun dan nama akun 457 untuk membentuk <strong>kontak</strong>. Hal ini memudahkan menampilkan dan memodifikasi semua data 458 yang telah dikumpulkan pengguna untuk seseorang. Penyedia Kontak mengelola pembuatan baris 459 kontak baru, dan agregasi kontak mentah dengan baris kontak yang ada. Baik aplikasi maupun adaptor sinkronisasi 460 tidak boleh menambahkan kontak dan sebagian kolom dalam baris kontak yang bersifat hanya baca. 461 </p> 462 <p class="note"> 463 <strong>Catatan:</strong> Jika Anda mencoba menambahkan kontak ke Penyedia Kontak dengan 464 {@link android.content.ContentResolver#insert(Uri,ContentValues) insert()}, Anda akan mendapatkan 465 eksepsi {@link java.lang.UnsupportedOperationException}. Jika Anda mencoba memperbarui sebuah kolom 466 yang tercantum sebagai "hanya-baca", pembaruan akan diabaikan. 467 </p> 468 <p> 469 Penyedia Kontak membuat kontak baru untuk merespons penambahan kontak mentah baru 470 yang tidak cocok dengan kontak yang ada. Penyedia juga melakukan ini jika data 471 kontak mentah yang ada berubah sehingga tidak lagi cocok dengan kontak yang 472 sebelumnya dihubungkan. Jika aplikasi atau adaptor sinkronisasi membuat kontak mentah baru yang 473 <em>memang</em> cocok dengan kontak yang ada, kontak mentah baru akan diagregasikan ke kontak 474 yang ada. 475 </p> 476 <p> 477 Penyedia Kontak menautkan baris kontak ke baris kontak mentahnya dengan kolom 478 <code>_ID</code> dari baris kontak dalam tabel {@link android.provider.ContactsContract.Contacts Contacts}. 479 Kolom <code>CONTACT_ID</code> tabel kontak mentah 480 {@link android.provider.ContactsContract.RawContacts} berisi nilai <code>_ID</code> untuk 481 baris kontak yang dikaitkan dengan tiap baris kontak mentah. 482 </p> 483 <p> 484 Tabel {@link android.provider.ContactsContract.Contacts} juga memiliki kolom 485 {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} yang merupakan 486 tautan "permanen" ke baris kontak. Karena memelihara kontak 487 secara otomatis, Penyedia Kontak bisa mengubah nilai {@code android.provider.BaseColumns#_ID} baris kontak 488 untuk merespons agregasi atau sinkronisasi. Sekalipun ini terjadi, URI konten 489 {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI} yang dikombinasikan dengan 490 {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} kontak akan tetap 491 menunjuk ke baris kontak itu, sehingga Anda bisa menggunakan 492 {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} 493 untuk memelihara tautan ke kontak "favorit", dan seterusnya. Kolom ini memiliki formatnya sendiri, yang 494 tidak terkait dengan format kolom {@code android.provider.BaseColumns#_ID}. 495 </p> 496 <p> 497 Gambar 3 menampilkan cara ketiga tabel utama terkait satu sama lain. 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>Gambar 3.</strong> Hubungan tabel Contacts, Raw Contacts, dan Details. 502 </p> 503 <h2 id="Sources">Data Dari Adaptor Sinkronisasi</h2> 504 <p> 505 Pengguna memasukkan data kontak secara langsung ke dalam perangkat, namun data juga mengalir masuk ke Penyedia Kontak 506 dari layanan web melalui <strong>adaptor sinkronisasi</strong>, yang mengotomatiskan 507 transfer data antara perangkat dan layanan. Adaptor sinkronisasi berjalan di latar belakang 508 di bawah kontrol sistem, dan memanggil metode {@link android.content.ContentResolver} 509 untuk mengelola data. 510 </p> 511 <p> 512 Di Android, layanan web yang digunakan adaptor sinkronisasi diidentifikasi melalui tipe akun. 513 Setiap adaptor sinkronisasi bekerja dengan satu tipe akun, tetapi bisa mendukung beberapa nama akun untuk 514 tipe itu. Tipe akun dan nama akun dijelaskan secara singkat di bagian 515 <a href="#RawContactsExample">Sumber data kontak mentah</a>. Definisi berikut menyediakan 516 detail selengkapnya, dan menjelaskan cara tipe dan nama akun berkaitan dengan adaptor sinkronisasi dan layanan. 517 </p> 518 <dl> 519 <dt> 520 Tipe akun 521 </dt> 522 <dd> 523 Mengidentifikasi layanan tempat pengguna menyimpan data. Sering kali, pengguna harus 524 mengautentikasi diri dengan layanan. Misalnya, Google Contacts adalah tipe akun, yang diidentifikasi 525 dengan kode <code>google.com</code>. Nilai ini sesuai dengan tipe akun yang digunakan oleh 526 {@link android.accounts.AccountManager}. 527 </dd> 528 <dt> 529 Nama akun 530 </dt> 531 <dd> 532 Mengidentifikasi akun atau login tertentu untuk suatu tipe akun. Akun Google Contacts 533 sama dengan akun Google, yang memiliki alamat email sebagai nama akun. 534 Layanan lain mungkin menggunakan nama pengguna satu-kata atau identitas berupa angka. 535 </dd> 536 </dl> 537 <p> 538 Tipe akun tidak harus unik. Pengguna boleh mengonfigurasi beberapa akun Google Contacts 539 dan mengunduh data ke Penyedia Kontak; ini mungkin terjadi jika pengguna memiliki satu set 540 kontak pribadi untuk satu nama akun pribadi, dan satu set lagi untuk pekerjaan. Nama akun 541 biasanya unik. Bersama-sama, keduanya mengidentifikasi aliran data tertentu antara Penyedia Kontak dan 542 layanan eksternal. 543 </p> 544 <p> 545 Jika Anda ingin mentransfer data layanan ke Penyedia Kontak, Anda perlu menulis 546 adaptor sinkronisasi sendiri. Hal ini dijelaskan lebih detail di bagian 547 <a href="#SyncAdapters">Adaptor Sinkronisasi Penyedia Kontak</a>. 548 </p> 549 <p> 550 Gambar 4 menampilkan cara Penyedia Kontak dimasukkan ke dalam aliran data 551 tentang orang. Dalam kotak bertanda "sync adapters", setiap adaptor diberi label menurut tipe akunnya. 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>Gambar 4.</strong> Aliran data Penyedia Kontak. 556 </p> 557 <h2 id="Permissions">Izin yang Diperlukan</h2> 558 <p> 559 Aplikasi yang ingin mengakses Penyedia Kontak harus meminta izin 560 berikut: 561 </p> 562 <dl> 563 <dt>Akses baca ke satu atau beberapa tabel</dt> 564 <dd> 565 {@link android.Manifest.permission#READ_CONTACTS}, yang ditetapkan dalam 566 <code>AndroidManifest.xml</code> dengan elemen 567 <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"> 568 <uses-permission></a></code> sebagai 569 <code><uses-permission android:name="android.permission.READ_CONTACTS"></code>. 570 </dd> 571 <dt>Akses tulis ke satu atau beberapa tabel</dt> 572 <dd> 573 {@link android.Manifest.permission#WRITE_CONTACTS}, yang ditetapkan dalam 574 <code>AndroidManifest.xml</code> dengan elemen 575 <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"> 576 <uses-permission></a></code> sebagai 577 <code><uses-permission android:name="android.permission.WRITE_CONTACTS"></code>. 578 </dd> 579 </dl> 580 <p> 581 Izin ini tidak diperluas ke data profil pengguna. Profil pengguna dan izin 582 yang diperlukan dibahas di bagian berikut, 583 <a href="#UserProfile">Profil Pengguna</a>. 584 </p> 585 <p> 586 Ingatlah bahwa data kontak pengguna bersifat pribadi dan sensitif. Pengguna mempersoalkan 587 privasinya, sehingga tidak ingin aplikasi mengumpulkan data tentang diri atau kontak mereka. 588 Jika alasan Anda memerlukan izin untuk mengakses data kontak tidak jelas, pengguna mungkin memberi 589 aplikasi Anda peringkat rendah atau langsung menolak menginstalnya. 590 </p> 591 <h2 id="UserProfile">Profil Pengguna</h2> 592 <p> 593 Tabel {@link android.provider.ContactsContract.Contacts} berisi satu baris yang berisi 594 data profil untuk pengguna perangkat. Data ini menjelaskan data perangkat <code>user</code> bukannya 595 salah satu kontak pengguna. Baris kontak profil ditautkan ke baris 596 kontak mentah untuk setiap sistem yang menggunakan profil. 597 Setiap baris kontak mentah profil bisa memiliki beberapa baris data. Konstanta untuk mengakses profil 598 pengguna tersedia dalam kelas {@link android.provider.ContactsContract.Profile}. 599 </p> 600 <p> 601 Akses ke profil pengguna memerlukan izin khusus. Selain itu, izin 602 {@link android.Manifest.permission#READ_CONTACTS} dan 603 {@link android.Manifest.permission#WRITE_CONTACTS} diperlukan untuk membaca dan menulis, akses 604 ke profil pengguna memerlukan masing-masing izin {@code android.Manifest.permission#READ_PROFILE} dan 605 {@code android.Manifest.permission#WRITE_PROFILE} untuk akses baca dan tulis. 606 607 </p> 608 <p> 609 Ingatlah bahwa Anda harus mempertimbangkan profil pengguna bersifat sensitif. Izin 610 {@code android.Manifest.permission#READ_PROFILE} memungkinkan Anda mengakses data yang mengidentifikasi secara pribadi 611 pengguna perangkat. Pastikan memberi tahu pengguna alasan 612 Anda memerlukan izin akses profil pengguna dalam keterangan aplikasi Anda. 613 </p> 614 <p> 615 Untuk mengambil baris kontak berisi profil pengguna, 616 panggil {@link android.content.ContentResolver#query(Uri,String[], String, String[], String) 617 ContentResolver.query()}. Atur URI konten ke 618 {@link android.provider.ContactsContract.Profile#CONTENT_URI} dan jangan sediakan 619 kriteria pemilihan apa pun. Anda juga bisa menggunakan URI konten ini sebagai URI dasar untuk mengambil kontak 620 mentah atau data untuk profil. Misalnya, cuplikan kode ini mengambil data untuk profil: 621 </p> 622 <pre> 623 // Sets the columns to retrieve for the user profile 624 mProjection = 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 633 mProfileCursor = 634 getContentResolver().query( 635 Profile.CONTENT_URI, 636 mProjection , 637 null, 638 null, 639 null); 640 </pre> 641 <p class="note"> 642 <strong>Catatan:</strong> Jika Anda mengambil beberapa baris kontak, dan ingin menentukan apakah salah satu baris 643 adalah profil pengguna, uji 644 kolom {@link android.provider.ContactsContract.ContactsColumns#IS_USER_PROFILE} pada baris tersebut. Kolom ini 645 diatur ke "1" jika kontak adalah profil pengguna. 646 </p> 647 <h2 id="ContactsProviderMetadata">Metadata Penyedia Kontak</h2> 648 <p> 649 Penyedia Kontak mengelola data yang mencatat status data kontak dalam 650 repository. Metadata repository ini disimpan di berbagai tempat, termasuk baris-baris tabel 651 Raw Contacts, Data, dan Contacts, 652 tabel {@link android.provider.ContactsContract.Settings}, dan 653 tabel {@link android.provider.ContactsContract.SyncState}. Tabel berikut menampilkan 654 efek setiap potongan metadata ini: 655 </p> 656 <p class="table-caption" id="table3"> 657 <strong>Tabel 3.</strong> Metadata di Penyedia Kontak</p> 658 <table> 659 <tr> 660 <th scope="col">Tabel</th> 661 <th scope="col">Kolom</th> 662 <th scope="col">Nilai</th> 663 <th scope="col">Arti</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" - tidak berubah sejak sinkronisasi terakhir.</td> 669 <td rowspan="2"> 670 Menandai kontak mentah yang berubah pada perangkat dan telah disinkronkan kembali ke 671 server. Nilai diatur secara otomatis oleh Penyedia Kontak bila aplikasi 672 Android memperbarui baris. 673 <p> 674 Adaptor sinkronisasi yang memodifikasi kontak mentah atau tabel data harus selalu menambahkan 675 string {@link android.provider.ContactsContract#CALLER_IS_SYNCADAPTER} ke 676 URI konten yang digunakannya. Ini mencegah penyedia menandai baris sebagai kotor. 677 Sebaliknya, modifikasi oleh adaptor sinkronisasi tampak seperti modifikasi lokal dan 678 dikirim ke server, meskipun server adalah sumber modifikasi. 679 </p> 680 </td> 681 </tr> 682 <tr> 683 <td>"1" - berubah sejak sinkronisasi terakhir, harus disinkronkan kembali ke server.</td> 684 </tr> 685 <tr> 686 <td>{@link android.provider.ContactsContract.RawContacts}</td> 687 <td>{@link android.provider.ContactsContract.SyncColumns#VERSION}</td> 688 <td>Nomor versi baris ini.</td> 689 <td> 690 Penyedia Kontak menambahkan nilai ini secara otomatis bila baris atau 691 data terkaitnya berubah. 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>Nomor versi baris ini.</td> 698 <td> 699 Penyedia Kontak menambahkan nilai ini secara otomatis bila baris data 700 berubah. 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 Nilai string yang mengidentifikasi secara unik kontak mentah ini ke akun tempat 708 kontak dibuat. 709 </td> 710 <td> 711 Bila adaptor sinkronisasi membuat kontak mentah baru, kolom ini harus diatur ke 712 ID unik server untuk kontak mentah itu. Bila aplikasi Android membuat kontak mentah 713 baru, aplikasi harus membiarkan kolom ini kosong. Ini mengisyaratkan pada adaptor 714 sinkronisasi bahwa adaptor harus membuat kontak mentah baru pada server, dan mendapatkan 715 nilai untuk {@link android.provider.ContactsContract.SyncColumns#SOURCE_ID}. 716 <p> 717 Khususnya, id sumber harus <strong>unik</strong> untuk setiap tipe 718 akun dan stabil di semua sinkronisasi: 719 </p> 720 <ul> 721 <li> 722 Unik: Setiap kontak mentah untuk satu akun harus memiliki id sumbernya sendiri. Jika Anda 723 tidak memberlakukan aturan ini, masalah akan timbul dalam aplikasi kontak. 724 Perhatikan bahwa dua kontak mentah untuk tipe akun yang <em>sama</em> boleh memiliki 725 id sumber yang sama. Misalnya, kontak mentah "Thomas Higginson" untuk 726 akun {@code emily.dickinson (a] gmail.com} boleh memiliki id sumber 727 yang sama dengan kontak mentah "Thomas Higginson" untuk akun 728 {@code emilyd (a] gmail.com}. 729 </li> 730 <li> 731 Stabil: Id sumber adalah bagian tetap dari data layanan online untuk 732 kontak mentah. Misalnya, jika pengguna membersihkan Contacts Storage dari 733 pengaturan aplikasi dan menyinkronkan ulang, kontak mentah yang dipulihkan akan memiliki id sumber 734 yang sama dengan sebelumnya. Jika Anda tidak memberlakukan hal ini, pintasan akan berhenti 735 berfungsi. 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" - Kontak dalam grup ini tidak boleh terlihat dalam UI aplikasi Android.</td> 744 <td> 745 Kolom ini digunakan untuk kompatibilitas dengan server yang memungkinkan pengguna menyembunyikan kontak dalam 746 grup tertentu. 747 </td> 748 </tr> 749 <tr> 750 <td>"1" - Kontak dalam grup ini boleh terlihat dalam UI aplikasi.</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" - Untuk akun dan tipe akun ini, kontak yang bukan milik grup 758 tidak akan terlihat pada UI aplikasi Android. 759 </td> 760 <td rowspan="2"> 761 Secara default, kontak tidak terlihat jika tidak satu pun kontak mentahnya milik grup 762 (Keanggotaan grup untuk kontak mentah ditandai oleh satu atau beberapa baris 763 {@link android.provider.ContactsContract.CommonDataKinds.GroupMembership} 764 dalam tabel {@link android.provider.ContactsContract.Data}). 765 Dengan mengatur flag ini dalam baris tabel {@link android.provider.ContactsContract.Settings} 766 untuk tipe akun dan akun, Anda bisa memaksakan kontak tanpa grup agar terlihat. 767 Satu kegunaan flag ini adalah menampilkan kontak dari server yang tidak menggunakan grup. 768 </td> 769 </tr> 770 <tr> 771 <td> 772 "1" - Untuk akun dan tipe akun ini, kontak yang bukan milik grup 773 akan terlihat pada UI aplikasi. 774 </td> 775 776 </tr> 777 <tr> 778 <td>{@link android.provider.ContactsContract.SyncState}</td> 779 <td>(semua)</td> 780 <td> 781 Gunakan tabel ini untuk menyimpan metadata bagi adaptor sinkronisasi Anda. 782 </td> 783 <td> 784 Dengan tabel ini, Anda bisa menyimpan status sinkronisasi dan data lain yang terkait dengan sinkronisasi secara persisten pada 785 perangkat. 786 </td> 787 </tr> 788 </table> 789 <h2 id="Access">Akses Penyedia Kontak</h2> 790 <p> 791 Bagian ini menjelaskan panduan untuk mengakses data dari Penyedia Kontak, yang berfokus pada 792 hal-hal berikut: 793 </p> 794 <ul> 795 <li> 796 Query entitas. 797 </li> 798 <li> 799 Modifikasi batch. 800 </li> 801 <li> 802 Pengambilan dan modifikasi dengan intent. 803 </li> 804 <li> 805 Integritas data. 806 </li> 807 </ul> 808 <p> 809 Membuat modifikasi dari adaptor sinkronisasi juga secara lebih detail di bagian 810 <a href="#SyncAdapters">Adaptor Sinkronisasi Penyedia Kontak</a>. 811 </p> 812 <h3 id="Entities">Membuat query entitas</h3> 813 <p> 814 Karena disusun secara hierarki, tabel-tabel Penyedia Kontak sering kali berguna untuk 815 mengambil baris dan semua baris "anak" yang ditautkan dengannya. Misalnya, untuk menampilkan 816 semua informasi untuk satu orang, Anda mungkin ingin mengambil semua 817 baris {@link android.provider.ContactsContract.RawContacts} untuk satu baris 818 {@link android.provider.ContactsContract.Contacts}, atau semua 819 baris {@link android.provider.ContactsContract.CommonDataKinds.Email} untuk satu baris 820 {@link android.provider.ContactsContract.RawContacts}. Untuk memudahkan hal ini, Penyedia Kontak 821 menawarkan konstruksi <strong>entitas</strong>, yang berfungsi seperti gabungan database di antara 822 tabel-tabel. 823 </p> 824 <p> 825 Entitas adalah seperti tabel yang terdiri atas kolom-kolom terpilih dari tabel induk dan tabel anaknya. 826 Bila membuat query sebuah entitas, Anda memberikan proyeksi dan kriteria pencarian berdasarkan kolom-kolom 827 yang tersedia dari entitas itu. Hasilnya adalah sebuah {@link android.database.Cursor} yang 828 berisi satu baris untuk setiap baris tabel anak yang diambil. Misalnya, jika Anda membuat query 829 {@link android.provider.ContactsContract.Contacts.Entity} untuk satu nama kontak 830 dan semua baris {@link android.provider.ContactsContract.CommonDataKinds.Email} untuk semua 831 kontak mentah bagi nama itu, Anda akan mendapatkan kembali {@link android.database.Cursor} berisi satu baris 832 untuk setiap baris {@link android.provider.ContactsContract.CommonDataKinds.Email}. 833 </p> 834 <p> 835 Entitas menyederhanakan query. Dengan entitas, Anda bisa mengambil semua data kontak untuk satu 836 kontak atau kontak mentah sekaligus, sebagai ganti harus membuat query tabel induk terlebih dahulu untuk mendapatkan 837 ID, lalu harus membuat query tabel anak dengan ID itu. Selain itu, Penyedia Kontak akan memproses 838 query terhadap entitas dalam satu transaksi, yang memastikan bahwa data yang diambil 839 konsisten secara internal. 840 </p> 841 <p class="note"> 842 <strong>Catatan:</strong> Entitas biasanya tidak berisi semua kolom tabel induk dan 843 anak. Jika Anda mencoba menggunakan nama kolom yang tidak ada dalam daftar konstanta 844 nama kolom untuk entitas, Anda akan mendapatkan {@link java.lang.Exception}. 845 </p> 846 <p> 847 Cuplikan berikut menampilkan cara mengambil semua baris kontak mentah untuk sebuah kontak. Cuplikan ini 848 adalah bagian dari aplikasi lebih besar yang memiliki dua aktivitas, "main" dan "detail". Aktivitas utama 849 menampilkan daftar baris kontak; bila pengguna memilih satu baris, aktivitas akan mengirimkan ID-nya ke aktivitas 850 detail. Aktivitas detail menggunakan{@link android.provider.ContactsContract.Contacts.Entity} 851 untuk menampilkan semua baris data dari semua kontak mentah yang dikaitkan dengan kontak 852 terpilih. 853 </p> 854 <p> 855 Cuplikan ini diambil dari aktivitas "detail": 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 886 public 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 Bila selesai dimuat, {@link android.app.LoaderManager} akan memicu callback ke 925 {@link android.app.LoaderManager.LoaderCallbacks#onLoadFinished(Loader, D) 926 onLoadFinished()}. Salah satu argumen masuk pada metode ini adalah 927 {@link android.database.Cursor} bersama hasil query. Dalam aplikasi Anda sendiri, Anda bisa memperoleh 928 data dari {@link android.database.Cursor} ini untuk menampilkannya atau menggunakannya lebih jauh. 929 </p> 930 <h3 id="Transactions">Modifikasi batch</h3> 931 <p> 932 Bila memungkinkan, Anda harus menyisipkan, memperbarui, dan menghapus data dalam Penyedia Kontak dengan 933 "batch mode", dengan membuat {@link java.util.ArrayList} dari 934 objek-objek {@link android.content.ContentProviderOperation} dan memanggil 935 {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}. Karena 936 Penyedia Kontak menjalankan semua operasi dalam satu 937 {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} transaksi, 938 modifikasi Anda tidak akan pernah meninggalkan repository kontak dalam keadaan 939 tidak konsisten. Modifikasi batch juga memudahkan penyisipan kontak mentah dan data detailnya 940 sekaligus. 941 </p> 942 <p class="note"> 943 <strong>Catatan:</strong> Untuk memodifikasi <em>satu</em> kontak mentah, pertimbangkan untuk mengirim intent ke 944 aplikasi kontak perangkat daripada menangani modifikasi dalam aplikasi Anda. 945 Cara ini dijelaskan lebih detail di bagian 946 <a href="#Intents">Pengambilan dan modifikasi dengan intent</a>. 947 </p> 948 <h4>Yield point</h4> 949 <p> 950 Modifikasi batch yang berisi operasi dalam jumlah besar bisa memblokir proses lain, 951 yang mengakibatkan pengalaman pengguna yang buruk secara keseluruhan. Untuk menata semua modifikasi yang ingin Anda 952 jalankan dalam sesedikit mungkin daftar terpisah, sambil mencegah modifikasi dari 953 memblokir sistem, Anda harus menetapkan <strong>yield point</strong> untuk satu atau beberapa operasi. 954 Yield point (titik hasil) adalah objek {@link android.content.ContentProviderOperation} yang mengatur 955 nilai {@link android.content.ContentProviderOperation#isYieldAllowed()}-nya ke 956 <code>true</code>. Bila menemui yield point, Penyedia Kontak akan menghentikan pekerjaannya untuk 957 membiarkan proses lain berjalan dan menutup transaksi saat ini. Bila dimulai lagi, penyedia akan 958 melanjutkan dengan operasi berikutnya di {@link java.util.ArrayList} dan memulai transaksi 959 baru. 960 </p> 961 <p> 962 Yield point memang menyebabkan lebih dari satu transaksi per panggilan ke 963 {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}. Karena 964 itu, Anda harus menetapkan yield point pada operasi terakhir untuk satu set baris terkait. 965 Misalnya, Anda harus menetapkan yield point pada operasi terakhir di satu set yang menambahkan 966 baris kontak mentah dan baris data terkait, atau operasi terakhir untuk satu set baris yang terkait 967 dengan satu kontak. 968 </p> 969 <p> 970 Yield point juga merupakan unit operasi atomis. Semua akses antara dua yield point bisa 971 saja berhasil atau gagal sebagai satu unit. Jika Anda mengatur yield point, operasi 972 atomis terkecil adalah seluruh batch operasi. Jika menggunakan yield point, Anda akan mencegah 973 operasi menurunkan kinerja sistem, sekaligus memastikan subset 974 operasi bersifat atomis. 975 </p> 976 <h4>Acuan balik modifikasi</h4> 977 <p> 978 Saat Anda menyisipkan baris kontak mentah baru dan baris data terkaitnya sebagai satu set 979 objek {@link android.content.ContentProviderOperation}, Anda harus menautkan baris data ke 980 baris kontak mentah dengan memasukkan nilai 981 {@code android.provider.BaseColumns#_ID} kontak mentah sebagai 982 nilai {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID}. Akan tetapi, nilai 983 ini tidak tersedia saat Anda membuat {@link android.content.ContentProviderOperation} 984 untuk baris data, karena Anda belum menerapkan 985 {@link android.content.ContentProviderOperation} untuk baris kontak mentah. Solusinya, 986 kelas {@link android.content.ContentProviderOperation.Builder} memiliki metode 987 {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}. 988 Metode ini memungkinkan Anda menyisipkan atau mengubah kolom dengan 989 hasil dari operasi sebelumnya. 990 </p> 991 <p> 992 Metode {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()} 993 memiliki dua argumen: 994 </p> 995 <dl> 996 <dt> 997 <code>key</code> 998 </dt> 999 <dd> 1000 Kunci dari pasangan kunci-nilai. Nilai argumen ini harus berupa nama kolom 1001 dalam tabel yang Anda modifikasi. 1002 </dd> 1003 <dt> 1004 <code>previousResult</code> 1005 </dt> 1006 <dd> 1007 Indeks berbasis 0 dari nilai pada larik 1008 objek {@link android.content.ContentProviderResult} dari 1009 {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}. Saat 1010 operasi batch diterapkan, hasil tiap operasi akan disimpan dalam 1011 larik hasil antara. Nilai <code>previousResult</code> adalah indeks 1012 dari salah satu hasil ini, yang diambil dan disimpan bersama nilai <code>key</code>. 1013 Cara ini memungkinkan Anda menyisipkan record kontak mentah baru dan mendapatkan kembali nilai 1014 {@code android.provider.BaseColumns#_ID}-nya, lalu membuat "acuan balik" ke 1015 nilai itu saat Anda menambahkan baris {@link android.provider.ContactsContract.Data}. 1016 <p> 1017 Seluruh larik hasil dibuat saat Anda memanggil 1018 {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} untuk pertama kali, 1019 dengan ukuran setara dengan ukuran {@link java.util.ArrayList} dari 1020 objek {@link android.content.ContentProviderOperation} yang Anda sediakan. Akan tetapi, semua 1021 elemen dalam larik hasil diatur ke <code>null</code>, dan jika Anda mencoba 1022 melakukan acuan balik ke hasil untuk operasi yang belum diterapkan, 1023 {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()} 1024 akan mengeluarkan {@link java.lang.Exception}. 1025 1026 </p> 1027 </dd> 1028 </dl> 1029 <p> 1030 Cuplikan kode berikut menampilkan cara menyisipkan kontak mentah baru dan data secara batch. Cuplikan kode ini 1031 menyertakan kode yang menetapkan yield point dan menggunakan acuan balik. Cuplikan kode ini adalah 1032 versi perluasan dari metode<code>createContacEntry()</code>, yang merupakan bagian dari kelas 1033 <code>ContactAdder</code> dalam 1034 aplikasi contoh <code><a href="{@docRoot}resources/samples/ContactManager/index.html"> 1035 Contact Manager</a></code>. 1036 </p> 1037 <p> 1038 Cuplikan pertama mengambil data kontak dari UI. Pada saat ini, pengguna sudah 1039 memilih akun tempat kontak mentah baru harus ditambahkan. 1040 </p> 1041 <pre> 1042 // Creates a contact entry from the current UI values, using the currently-selected account. 1043 protected 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 Cuplikan berikutnya membuat operasi untuk menyisipkan baris kontak mentah ke dalam 1059 tabel {@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 Berikutnya, kode akan membuat baris data untuk baris-baris nama tampilan, telepon, dan email. 1087 </p> 1088 <p> 1089 Setiap objek pembangun operasi menggunakan 1090 {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()} 1091 untuk mendapatkan 1092 {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID}. Acuan menunjuk 1093 balik ke objek {@link android.content.ContentProviderResult} dari operasi pertama, 1094 yang menambahkan baris kontak mentah dan mengembalikan nilai {@code android.provider.BaseColumns#_ID} 1095 barunya. Hasilnya, setiap data ditautkan secara otomatis oleh 1096 {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID}-nya 1097 ke baris {@link android.provider.ContactsContract.RawContacts} baru yang memilikinya. 1098 </p> 1099 <p> 1100 Objek {@link android.content.ContentProviderOperation.Builder} yang menambahkan baris email 1101 diberi flag {@link android.content.ContentProviderOperation.Builder#withYieldAllowed(boolean) 1102 withYieldAllowed()}, yang mengatur yield point: 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 Cuplikan terakhir menampilkan panggilan ke 1176 {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} yang 1177 menyisipkan baris-baris kontak mentah dan data baru. 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 Operasi batch juga memungkinkan Anda menerapkan <strong>kontrol konkurensi optimistis</strong>, 1209 sebuah metode yang menerapkan transaksi modifikasi tanpa harus mengunci repository yang mendasari. 1210 Untuk menggunakan metode ini, terapkan transaksi dan periksa modifikasi lain yang 1211 mungkin telah dibuat bersamaan. Jika ternyata modifikasi tidak konsisten, Anda 1212 mengembalikan transaksi ke kondisi semula dan mencobanya kembali. 1213 </p> 1214 <p> 1215 Kontrol konkurensi optimistis berguna untuk perangkat seluler, apabila hanya ada satu pengguna setiap 1216 kalinya, dan akses simultan ke repository data jarang terjadi. Karena penguncian tidak digunakan, 1217 tidak ada waktu yang terbuang untuk memasang kunci atau menunggu transaksi lain untuk melepas kunci. 1218 </p> 1219 <p> 1220 Untuk menggunakan kontrol konkurensi optimistis saat memperbarui satu baris 1221 {@link android.provider.ContactsContract.RawContacts}, ikuti langkah-langkah ini: 1222 </p> 1223 <ol> 1224 <li> 1225 Ambil kolom {@link android.provider.ContactsContract.SyncColumns#VERSION} 1226 kontak mentah bersama data lain yang Anda ambil. 1227 </li> 1228 <li> 1229 Buat sebuah objek {@link android.content.ContentProviderOperation.Builder} yang cocok untuk 1230 memberlakukan batasan, dengan menggunakan metode 1231 {@link android.content.ContentProviderOperation#newAssertQuery(Uri)}. Untuk URI konten, 1232 gunakan {@link android.provider.ContactsContract.RawContacts#CONTENT_URI 1233 RawContacts.CONTENT_URI} 1234 dengan {@code android.provider.BaseColumns#_ID} kontak mentah yang ditambahkan padanya. 1235 </li> 1236 <li> 1237 Untuk objek {@link android.content.ContentProviderOperation.Builder}, panggil 1238 {@link android.content.ContentProviderOperation.Builder#withValue(String, Object) 1239 withValue()} untuk membandingkan kolom {@link android.provider.ContactsContract.SyncColumns#VERSION} 1240 dengan nomor versi yang baru saja Anda ambil. 1241 </li> 1242 <li> 1243 Untuk {@link android.content.ContentProviderOperation.Builder} yang sama, panggil 1244 {@link android.content.ContentProviderOperation.Builder#withExpectedCount(int) 1245 withExpectedCount()} untuk memastikan bahwa hanya satu baris yang diuji oleh pernyataan ini. 1246 </li> 1247 <li> 1248 Panggil {@link android.content.ContentProviderOperation.Builder#build()} untuk membuat 1249 objek {@link android.content.ContentProviderOperation}, kemudian tambahkan objek ini sebagai 1250 objek pertama di {@link java.util.ArrayList} yang Anda teruskan ke 1251 {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}. 1252 </li> 1253 <li> 1254 Terapkan transaksi batch. 1255 </li> 1256 </ol> 1257 <p> 1258 Jika baris kontak mentah diperbarui oleh operasi lain antara waktu Anda membaca baris dan 1259 waktu Anda mencoba memodifikasinya, "asert" {@link android.content.ContentProviderOperation} 1260 akan gagal, dan seluruh batch operasi akan dibatalkan. Anda nanti bisa memilih untuk mencoba ulang 1261 batch atau melakukan tindakan lain. 1262 </p> 1263 <p> 1264 Cuplikan berikut memperagakan cara membuat "asert" 1265 {@link android.content.ContentProviderOperation} setelah membuat query satu kontak mentah yang menggunakan 1266 {@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 */ 1273 public 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 1283 Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, mRawContactID); 1284 1285 // Creates a builder for the assert operation 1286 ContentProviderOperation.Builder assertOp = ContentProviderOperation.netAssertQuery(rawContactUri); 1287 1288 // Adds the assertions to the assert operation: checks the version and count of rows tested 1289 assertOp.withValue(SyncColumns.VERSION, mVersion); 1290 assertOp.withExpectedCount(1); 1291 1292 // Creates an ArrayList to hold the ContentProviderOperation objects 1293 ArrayList ops = new ArrayList<ContentProviderOperationg>; 1294 1295 ops.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 1302 try 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">Pengambilan dan modifikasi dengan intent</h3> 1313 <p> 1314 Mengirimkan intent ke aplikasi kontak perangkat memungkinkan Anda mengakses Penyedia Kontak 1315 secara tidak langsung. Intent akan memulai UI aplikasi kontak perangkat, tempat pengguna bisa 1316 melakukan pekerjaan yang terkait dengan kontak. Dengan tipe akses ini, pengguna bisa: 1317 <ul> 1318 <li>Memilih kontak dari daftar dan meneruskannya ke aplikasi untuk pekerjaan lebih jauh.</li> 1319 <li>Mengedit data kontak yang ada.</li> 1320 <li>Memasukkan kontak mentah baru untuk akun mereka.</li> 1321 <li>Menghapus kontak atau data kontak.</li> 1322 </ul> 1323 <p> 1324 Jika pengguna menyisipkan atau memperbarui data, Anda bisa mengumpulkan data lebih dahulu dan mengirimkannya sebagai 1325 bagian dari intent. 1326 </p> 1327 <p> 1328 Bila Anda menggunakan intent untuk mengakses Penyedia Kontak melalui aplikasi kontak perangkat, Anda 1329 tidak perlu menulis UI atau kode sendiri untuk mengakses penyedia. Anda juga tidak harus 1330 meminta izin untuk membaca dari atau menulis ke penyedia. Aplikasi kontak perangkat bisa 1331 mendelegasikan izin membaca untuk kontak kepada Anda, dan karena Anda membuat modifikasi pada 1332 penyedia melalui aplikasi lain, Anda tidak perlu memiliki izin menulis. 1333 </p> 1334 <p> 1335 Proses umum pengiriman intent untuk mengakses penyedia dijelaskan secara detail dalam panduan 1336 <a href="{@docRoot}guide/topics/providers/content-provider-basics.html"> 1337 Dasar-Dasar Penyedia Konten</a> di bagian "Akses data melalui intent". Tindakan, 1338 tipe MIME, dan nilai data yang Anda gunakan untuk tugas yang tersedia dirangkum dalam Tabel 4, sedangkan 1339 nilai ekstra yang bisa Anda gunakan bersama 1340 {@link android.content.Intent#putExtra(String, String) putExtra()} tercantum dalam 1341 dokumentasi acuan untuk {@link android.provider.ContactsContract.Intents.Insert}: 1342 </p> 1343 <p class="table-caption" id="table4"> 1344 <strong>Tabel 4.</strong> Intent Penyedia Kontak. 1345 </p> 1346 <table style="width:75%"> 1347 <tr> 1348 <th scope="col" style="width:10%">Tugas</th> 1349 <th scope="col" style="width:5%">Tindakan</th> 1350 <th scope="col" style="width:10%">Data</th> 1351 <th scope="col" style="width:10%">Tipe MIME</th> 1352 <th scope="col" style="width:25%">Catatan</th> 1353 </tr> 1354 <tr> 1355 <td><strong>Memilih kontak dari daftar</strong></td> 1356 <td>{@link android.content.Intent#ACTION_PICK}</td> 1357 <td> 1358 Salah satu dari: 1359 <ul> 1360 <li> 1361 {@link android.provider.ContactsContract.Contacts#CONTENT_URI Contacts.CONTENT_URI}, 1362 yang menampilkan daftar kontak. 1363 </li> 1364 <li> 1365 {@link android.provider.ContactsContract.CommonDataKinds.Phone#CONTENT_URI Phone.CONTENT_URI}, 1366 yang menampilkan daftar nomor telepon untuk kontak mentah. 1367 </li> 1368 <li> 1369 {@link android.provider.ContactsContract.CommonDataKinds.StructuredPostal#CONTENT_URI 1370 StructuredPostal.CONTENT_URI}, 1371 yang menampilkan daftar alamat pos untuk kontak mentah. 1372 </li> 1373 <li> 1374 {@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_URI Email.CONTENT_URI}, 1375 yang menampilkan daftar alamat email untuk kontak baru. 1376 </li> 1377 </ul> 1378 </td> 1379 <td> 1380 Tidak digunakan 1381 </td> 1382 <td> 1383 Menampilkan daftar kontak mentah atau daftar data dari kontak mentah, sesuai dengan tipe 1384 URI konten yang Anda sediakan. 1385 <p> 1386 Panggil 1387 {@link android.app.Activity#startActivityForResult(Intent, int) startActivityForResult()}, 1388 yang menghasilkan URI konten dari baris terpilih. Bentuk URI adalah 1389 URI konten tabel dengan <code>LOOKUP_ID</code> baris yang ditambahkan padanya. 1390 Aplikasi kontak perangkat mendelegasikan izin membaca dan menulis untuk URI konten ini 1391 selama masa pakai aktivitas Anda. Lihat panduan 1392 <a href="{@docRoot}guide/topics/providers/content-provider-basics.html"> 1393 Dasar-Dasar Penyedia Konten</a> untuk detail selengkapnya. 1394 </p> 1395 </td> 1396 </tr> 1397 <tr> 1398 <td><strong>Menyisipkan kontak mentah baru</strong></td> 1399 <td>{@link android.provider.ContactsContract.Intents.Insert#ACTION Insert.ACTION}</td> 1400 <td>N/A</td> 1401 <td> 1402 {@link android.provider.ContactsContract.RawContacts#CONTENT_TYPE 1403 RawContacts.CONTENT_TYPE}, tipe MIME untuk satu set kontak mentah. 1404 </td> 1405 <td> 1406 Menampilkan layar <strong>Add Contact</strong> aplikasi kontak perangkat. Nilai 1407 ekstra yang Anda tambahkan ke intent akan ditampilkan. Jika dikirimkan bersama 1408 {@link android.app.Activity#startActivityForResult(Intent, int) startActivityForResult()}, 1409 URI konten dari kontak mentah yang baru saja ditambahkan akan dikembalikan ke 1410 {@link android.app.Activity#onActivityResult(int, int, Intent) onActivityResult()} 1411 metode callback aktivitas Anda pada argumen {@link android.content.Intent}, di 1412 bidang "data". Untuk mendapatkan nilainya, panggil {@link android.content.Intent#getData()}. 1413 </td> 1414 </tr> 1415 <tr> 1416 <td><strong>Mengedit kontak</strong></td> 1417 <td>{@link android.content.Intent#ACTION_EDIT}</td> 1418 <td> 1419 {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI} untuk 1420 kontak. Aktivitas editor memungkinkan pengguna mengedit setiap data yang dikaitkan 1421 dengan kontak ini. 1422 </td> 1423 <td> 1424 {@link android.provider.ContactsContract.Contacts#CONTENT_ITEM_TYPE 1425 Contacts.CONTENT_ITEM_TYPE}, kontak tunggal.</td> 1426 <td> 1427 Menampilkan layar Edit Contact dalam aplikasi kontak. Nilai ekstra yang Anda tambahkan 1428 ke intent akan ditampilkan. Bila pengguna mengklik <strong>Done</strong> untuk menyimpan 1429 hasil edit, aktivitas Anda kembali ke latar depan. 1430 </td> 1431 </tr> 1432 <tr> 1433 <td><strong>Menampilkan picker yang juga bisa menambahkan data.</strong></td> 1434 <td>{@link android.content.Intent#ACTION_INSERT_OR_EDIT}</td> 1435 <td> 1436 N/A 1437 </td> 1438 <td> 1439 {@link android.provider.ContactsContract.Contacts#CONTENT_ITEM_TYPE} 1440 </td> 1441 <td> 1442 Intent ini selalu menampilkan layar picker aplikasi kontak. Pengguna bisa memilih 1443 kontak untuk diedit, atau menambahkan kontak baru. Layar edit atau layar tambah 1444 akan muncul, sesuai dengan pilihan pengguna, dan data ekstra yang Anda kirimkan dalam intent 1445 akan ditampilkan. Jika aplikasi Anda menampilkan data kontak seperti email atau nomor telepon, gunakan 1446 intent ini untuk memungkinkan pengguna menambahkan data ke kontak yang ada. 1447 1448 <p class="note"> 1449 <strong>Catatan:</strong> Tidak perlu mengirimkan nilai nama dalam ekstra intent ini, 1450 karena pengguna selalu mengambil nama yang ada atau menambahkan nama baru. Lebih-lebih, 1451 jika Anda mengirimkan nama, dan pengguna memilih untuk melakukan edit, aplikasi kontak akan 1452 menampilkan nama yang Anda kirimkan, yang menimpa nilai sebelumnya. Jika pengguna tidak 1453 menyadari hal ini dan menyimpan hasil edit, nilai lama akan hilang. 1454 </p> 1455 </td> 1456 </tr> 1457 </table> 1458 <p> 1459 Aplikasi kontak perangkat tidak memperbolehkan Anda menghapus kontak mentah atau datanya dengan 1460 intent. Sebagai gantinya, untuk menghapus kontak mentah, gunakan 1461 {@link android.content.ContentResolver#delete(Uri, String, String[]) ContentResolver.delete()} 1462 atau {@link android.content.ContentProviderOperation#newDelete(Uri) 1463 ContentProviderOperation.newDelete()}. 1464 </p> 1465 <p> 1466 Cuplikan berikut menampilkan cara menyusun dan mengirimkan intent yang menyisipkan kontak dan data 1467 mentah baru: 1468 </p> 1469 <pre> 1470 // Gets values from the UI 1471 String name = mContactNameEditText.getText().toString(); 1472 String phone = mContactPhoneEditText.getText().toString(); 1473 String email = mContactEmailEditText.getText().toString(); 1474 1475 String company = mCompanyName.getText().toString(); 1476 String jobtitle = mJobTitle.getText().toString(); 1477 1478 // Creates a new intent for sending to the device's contacts application 1479 Intent insertIntent = new Intent(ContactsContract.Intents.Insert.ACTION); 1480 1481 // Sets the MIME type to the one expected by the insertion activity 1482 insertIntent.setType(ContactsContract.RawContacts.CONTENT_TYPE); 1483 1484 // Sets the new contact name 1485 insertIntent.putExtra(ContactsContract.Intents.Insert.NAME, name); 1486 1487 // Sets the new company and job title 1488 insertIntent.putExtra(ContactsContract.Intents.Insert.COMPANY, company); 1489 insertIntent.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 1496 ArrayList<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 1504 ContentValues rawContactRow = new ContentValues(); 1505 1506 // Adds the account type and name to the row 1507 rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType()); 1508 rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName()); 1509 1510 // Adds the row to the array 1511 contactData.add(rawContactRow); 1512 1513 /* 1514 * Sets up the phone number data row 1515 */ 1516 1517 // Sets up the row as a ContentValues object 1518 ContentValues phoneRow = new ContentValues(); 1519 1520 // Specifies the MIME type for this data row (all data rows must be marked by their type) 1521 phoneRow.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 1527 phoneRow.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone); 1528 1529 // Adds the row to the array 1530 contactData.add(phoneRow); 1531 1532 /* 1533 * Sets up the email data row 1534 */ 1535 1536 // Sets up the row as a ContentValues object 1537 ContentValues emailRow = new ContentValues(); 1538 1539 // Specifies the MIME type for this data row (all data rows must be marked by their type) 1540 emailRow.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 1546 emailRow.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email); 1547 1548 // Adds the row to the array 1549 contactData.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 */ 1556 insertIntent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contactData); 1557 1558 // Send out the intent to start the device's contacts app in its add contact activity. 1559 startActivity(insertIntent); 1560 </pre> 1561 <h3 id="DataIntegrity">Integritas data</h3> 1562 <p> 1563 Karena repository kontak berisi data penting dan sensitif yang diharapkan pengguna agar 1564 benar dan terbaru. Penyedia Kontak memiliki aturan yang didefinisikan dengan baik demi integritas data. Anda 1565 bertanggung jawab untuk mematuhi aturan ini saat memodifikasi data kontak. Aturan-aturan penting itu 1566 dicantumkan di sini: 1567 </p> 1568 <dl> 1569 <dt> 1570 Selalu tambahkan baris {@link android.provider.ContactsContract.CommonDataKinds.StructuredName} 1571 untuk setiap baris {@link android.provider.ContactsContract.RawContacts} yang Anda tambahkan. 1572 </dt> 1573 <dd> 1574 Baris {@link android.provider.ContactsContract.RawContacts} tanpa 1575 baris {@link android.provider.ContactsContract.CommonDataKinds.StructuredName} dalam 1576 tabel {@link android.provider.ContactsContract.Data} bisa menyebabkan masalah selama 1577 agregasi. 1578 </dd> 1579 <dt> 1580 Selalu tautkan baris {@link android.provider.ContactsContract.Data} baru ke baris 1581 {@link android.provider.ContactsContract.RawContacts} induknya. 1582 </dt> 1583 <dd> 1584 Baris {@link android.provider.ContactsContract.Data} yang tidak ditautkan ke 1585 {@link android.provider.ContactsContract.RawContacts} tidak akan terlihat dalam aplikasi kontak 1586 perangkat, dan itu bisa menimbulkan masalah dengan adaptor sinkronisasi. 1587 </dd> 1588 <dt> 1589 Ubah data hanya untuk kontak mentah yang Anda miliki. 1590 </dt> 1591 <dd> 1592 Ingatlah bahwa Penyedia Kontak biasanya mengelola data dari berbagai 1593 tipe akun/layanan online. Anda harus memastikan bahwa aplikasi Anda hanya memodifikasi 1594 atau menghapus data untuk baris milik Anda, dan bahwa aplikasi hanya menyisipkan data dengan 1595 tipe akun dan nama yang Anda kontrol. 1596 </dd> 1597 <dt> 1598 Selalu gunakan konstanta yang didefinisikan dalam {@link android.provider.ContactsContract} dan 1599 subkelasnya untuk otoritas, URI konten, URI path, nama kolom, tipe MIME, dan 1600 nilai {@link android.provider.ContactsContract.CommonDataKinds.CommonColumns#TYPE}. 1601 </dt> 1602 <dd> 1603 Menggunakan konstanta ini membantu Anda menghindari kesalahan. Anda juga akan diberi tahu dengan peringatan 1604 compiler jika salah satu konstanta sudah usang. 1605 </dd> 1606 </dl> 1607 <h3 id="CustomData">Baris data custom</h3> 1608 <p> 1609 Dengan membuat dan menggunakan tipe MIME custom sendiri, Anda bisa menyisipkan, mengedit, menghapus, dan mengambil 1610 baris data sendiri dalam tabel {@link android.provider.ContactsContract.Data}. Baris Anda 1611 dibatasi untuk menggunakan kolom yang didefinisikan dalam 1612 {@link android.provider.ContactsContract.DataColumns}, meskipun Anda bisa memetakan nama kolom 1613 bertipe spesifik sendiri ke nama kolom default. Dalam aplikasi kontak perangkat, 1614 data untuk baris Anda ditampilkan, tetapi tidak bisa diedit atau dihapus, dan pengguna tidak bisa menambahkan 1615 data lain. Untuk memudahkan pengguna mengubah baris data custom Anda, Anda harus menyediakan aktivitas 1616 editor dalam aplikasi Anda sendiri. 1617 </p> 1618 <p> 1619 Untuk menampilkan data custom, sediakan file <code>contacts.xml</code> berisi elemen 1620 <code><ContactsAccountType></code> dan satu atau beberapa elemen anak 1621 <code><ContactsDataKind></code>. Hal ini dijelaskan lebih detail di 1622 bagian <a href="#SocialStreamDataKind"><code><ContactsDataKind> element</code></a>. 1623 </p> 1624 <p> 1625 Untuk mengetahui selengkapnya tentang tipe MIME custom, bacalah panduan 1626 <a href="{@docRoot}guide/topics/providers/content-provider-creating.html"> 1627 Membuat Penyedia Konten</a>. 1628 </p> 1629 <h2 id="SyncAdapters">Adaptor Sinkronisasi Penyedia Kontak</h2> 1630 <p> 1631 Penyedia Kontak didesain khusus untuk menangani <strong>sinkronisasi</strong> 1632 data kontak antara perangkat dan layanan online. Hal ini memungkinkan pengguna mengunduh 1633 data yang ada dari perangkat baru dan mengunggah data yang ada ke akun baru. 1634 Sinkronisasi juga memastikan bahwa pengguna memiliki data terbaru, apa pun 1635 sumber penambahan dan perubahan itu. Keuntungan lain dari sinkronisasi adalah membuat 1636 data kontak tersedia sekalipun perangkat tidak terhubung ke jaringan. 1637 </p> 1638 <p> 1639 Walaupun Anda bisa menerapkan sinkronisasi dengan berbagai cara, sistem Android menyediakan 1640 kerangka kerja sinkronisasi plug-in yang mengotomatiskan tugas-tugas berikut: 1641 <ul> 1642 1643 <li> 1644 Memeriksa ketersediaan jaringan. 1645 </li> 1646 <li> 1647 Menjadwalkan dan menjalankan sinkronisasi, berdasarkan preferensi pengguna. 1648 </li> 1649 <li> 1650 Memulai kembali sinkronisasi yang telah berhenti. 1651 </li> 1652 </ul> 1653 <p> 1654 Untuk menggunakan kerangka kerja ini, Anda harus menyediakan plug-in adaptor sinkronisasi. Setiap adaptor sinkronisasi bersifat unik bagi 1655 layanan dan penyedia konten, tetapi mampu menangani beberapa nama akun untuk layanan yang sama. Kerangka 1656 kerja ini juga memungkinkan beberapa adaptor sinkronisasi untuk layanan dan penyedia yang sama. 1657 </p> 1658 <h3 id="SyncClassesFiles">Kelas dan file adaptor sinkronisasi</h3> 1659 <p> 1660 Anda mengimplementasikan adaptor sinkronisasi sebagai subkelas 1661 {@link android.content.AbstractThreadedSyncAdapter} dan menginstalnya sebagai bagian dari aplikasi 1662 Android. Sistem akan mempelajari adaptor sinkronisasi dari elemen-elemen di manifes 1663 aplikasi Anda dan dari file XML khusus yang ditunjuk oleh manifes. File XML mendefinisikan 1664 tipe akun untuk layanan online dan otoritas untuk penyedia konten, yang bersama-sama 1665 mengidentifikasi adaptor secara unik. Adaptor sinkronisasi tidak menjadi aktif hingga pengguna menambahkan 1666 akun untuk tipe akun adaptor sinkronisasi dan memungkinkan sinkronisasi untuk penyedia 1667 konten yang disinkronkan dengan adaptor sinkronisasi. Pada saat itu, sistem mulai mengelola adaptor, 1668 memanggilnya seperlunya untuk menyinkronkan antara penyedia konten dan server. 1669 </p> 1670 <p class="note"> 1671 <strong>Catatan:</strong> Menggunakan tipe akun sebagai bagian dari identifikasi adaptor sinkronisasi memungkinkan 1672 sistem mendeteksi dan menghimpun adaptor-adaptor sinkronisasi yang mengakses berbagai layanan dari 1673 organisasi yang sama. Misalnya, adaptor sinkronisasi untuk semua layanan online Google semuanya memiliki tipe akun 1674 yang sama <code>com.google</code>. Bila pengguna menambahkan akun Google ke perangkatnya, semua 1675 adaptor sinkronisasi yang terinstal untuk layanan Google akan dicantumkan bersama; setiap adaptor sinkronisasi 1676 yang tercantum akan menyinkronkan diri dengan berbagai penyedia konten pada perangkat. 1677 </p> 1678 <p> 1679 Karena sebagian besar layanan mengharuskan pengguna untuk memeriksa identitas sebelum mengakses 1680 data, sistem Android menawarkan kerangka kerja autentikasi yang serupa dengan, dan sering kali 1681 digunakan bersama, kerangka kerja adaptor sinkronisasi. Kerangka kerja autentikasi menggunakan 1682 autentikator plug-in yang merupakan subkelas 1683 {@link android.accounts.AbstractAccountAuthenticator}. Autentikator memeriksa 1684 identitas pengguna dalam langkah-langkah berikut: 1685 <ol> 1686 <li> 1687 Mengumpulkan nama pengguna, kata sandi, atau informasi serupa ( 1688 <strong>kredensial</strong> pengguna). 1689 </li> 1690 <li> 1691 Mengirimkan kredensial ke layanan 1692 </li> 1693 <li> 1694 Memeriksa balasan layanan. 1695 </li> 1696 </ol> 1697 <p> 1698 Jika layanan menerima kredensial, autentikator bisa 1699 menyimpan kredensial itu untuk digunakan nanti. Karena kerangka kerja autentikator plug-in, 1700 {@link android.accounts.AccountManager} bisa menyediakan akses ke setiap token autentikasi yang didukung suatu autentikator 1701 dan dipilihnya untuk diekspos, seperti token autentikasi OAuth2. 1702 </p> 1703 <p> 1704 Meskipun autentikasi tidak diharuskan, sebagian besar layanan kontak menggunakannya. 1705 Akan tetapi, Anda tidak wajib menggunakan kerangka kerja autentikasi Android untuk melakukan autentikasi. 1706 </p> 1707 <h3 id="SyncAdapterImplementing">Implementasi adaptor sinkronisasi</h3> 1708 <p> 1709 Untuk mengimplementasikan adaptor sinkronisasi bagi Penyedia Kontak, perlu Anda memulai dengan membuat 1710 aplikasi Android yang berisi elemen-elemen berikut: 1711 </p> 1712 <dl> 1713 <dt> 1714 Komponen {@link android.app.Service} yang merespons permintaan sistem untuk 1715 mengikat ke adaptor sinkronisasi. 1716 </dt> 1717 <dd> 1718 Bila sistem ingin menjalankan sinkronisasi, sistem akan memanggil metode 1719 {@link android.app.Service#onBind(Intent) onBind()} layanan untuk mendapatkan 1720 {@link android.os.IBinder} bagi adaptor sinkronisasi. Hal ini memungkinkan sistem melakukan 1721 panggilan lintas proses ke metode adaptor. 1722 <p> 1723 Dalam contoh aplikasi <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html"> 1724 Sample Sync Adapter</a>, nama kelas layanan ini adalah 1725 <code>com.example.android.samplesync.syncadapter.SyncService</code>. 1726 </p> 1727 </dd> 1728 <dt> 1729 Adaptor sinkronisasi yang sesungguhnya, diimplementasikan sebagai subkelas konkret dari 1730 {@link android.content.AbstractThreadedSyncAdapter}. 1731 </dt> 1732 <dd> 1733 Kelas ini melakukan pekerjaan mengunduh data dari server, mengunggah data ke 1734 perangkat, dan menyelesaikan konflik. Pekerjaan utama adaptor 1735 diselesaikan dengan metode {@link android.content.AbstractThreadedSyncAdapter#onPerformSync( 1736 Account, Bundle, String, ContentProviderClient, SyncResult) 1737 onPerformSync()}. Instance kelas ini harus dibuat sebagai singleton. 1738 <p> 1739 Dalam contoh aplikasi <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html"> 1740 Sample Sync Adapter</a>, adaptor sinkronisasi didefinisikan dalam kelas 1741 <code>com.example.android.samplesync.syncadapter.SyncAdapter</code>. 1742 </p> 1743 </dd> 1744 <dt> 1745 Subkelas {@link android.app.Application}. 1746 </dt> 1747 <dd> 1748 Kelas ini berfungsi sebagai pabrik untuk singleton adaptor sinkronisasi. Gunakan 1749 metode {@link android.app.Application#onCreate()} untuk membuat instance adaptor sinkronisasi , dan 1750 menyediakan metode "getter" statis untuk mengembalikan singleton ke 1751 metode {@link android.app.Service#onBind(Intent) onBind()} dari layanan 1752 adaptor sinkronisasi. 1753 </dd> 1754 <dt> 1755 <strong>Opsional:</strong> Komponen {@link android.app.Service} yang merespons 1756 permintaan dari sistem untuk autentikasi pengguna. 1757 </dt> 1758 <dd> 1759 {@link android.accounts.AccountManager} memulai layanan ini untuk memulai proses 1760 autentikasi. Metode {@link android.app.Service#onCreate()} layanan membuat instance 1761 objek autentikator. Bila sistem ingin mengautentikasi akun pengguna untuk 1762 adaptor sinkronisasi aplikasi, sistem akan memanggil metode 1763 {@link android.app.Service#onBind(Intent) onBind()} layanan guna mendapatkan 1764 {@link android.os.IBinder} bagi autentikator. Hal ini memungkinkan sistem melakukan 1765 panggilan lintas proses ke metode autentikator. 1766 <p> 1767 Dalam contoh aplikasi <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html"> 1768 Sample Sync Adapter</a>, nama kelas layanan ini adalah 1769 <code>com.example.android.samplesync.authenticator.AuthenticationService</code>. 1770 </p> 1771 </dd> 1772 <dt> 1773 <strong>Opsional:</strong> Subkelas konkret 1774 {@link android.accounts.AbstractAccountAuthenticator} yang menangani permintaan 1775 autentikasi. 1776 </dt> 1777 <dd> 1778 Kelas ini menyediakan metode yang dipicu {@link android.accounts.AccountManager} 1779 untuk mengautentikasi kredensial pengguna dengan layanan. Detail 1780 proses autentikasi sangat bervariasi, berdasarkan teknologi server yang digunakan. Anda harus 1781 mengacu ke dokumentasi bagi perangkat lunak server untuk mengetahui selengkapnya tentang autentikasi. 1782 <p> 1783 Dalam contoh aplikasi <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html"> 1784 Sample Sync Adapter</a>, autentikator didefinisikan dalam kelas 1785 <code>com.example.android.samplesync.authenticator.Authenticator</code>. 1786 </p> 1787 </dd> 1788 <dt> 1789 File XML yang mendefinisikan adaptor sinkronisasi dan autentikator bagi sistem. 1790 </dt> 1791 <dd> 1792 Komponen-komponen layanan adaptor sinkronisasi dan autentikator 1793 didefinisikan dalam elemen-elemen 1794 <code><<a href="{@docRoot}guide/topics/manifest/service-element.html">service</a>></code> 1795 di manifes aplikasi. Elemen-elemen ini 1796 berisi 1797 <code><<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>></code> 1798 elemen anak yang menyediakan data tertentu ke 1799 sistem: 1800 <ul> 1801 <li> 1802 Elemen 1803 <code><<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>></code> 1804 untuk layanan adaptor sinkronisasi menunjuk ke 1805 file XML <code>res/xml/syncadapter.xml</code>. Pada gilirannya, file ini mendefinisikan 1806 URI untuk layanan web yang akan disinkronkan dengan Penyedia Kontak, 1807 dan tipe akun untuk layanan web. 1808 </li> 1809 <li> 1810 <strong>Opsional:</strong> Elemen 1811 <code><<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>></code> 1812 untuk autentikator menunjuk ke file XML 1813 <code>res/xml/authenticator.xml</code>. Pada gilirannya, file ini menetapkan 1814 tipe akun yang didukung autentikator, serta sumber daya UI yang 1815 muncul selama proses autentikasi. Tipe akun yang ditetapkan dalam elemen ini 1816 harus sama dengan tipe akun yang ditetapkan untuk adaptor 1817 sinkronisasi. 1818 </li> 1819 </ul> 1820 </dd> 1821 </dl> 1822 <h2 id="SocialStream">Data Aliran Sosial</h2> 1823 <p> 1824 Tabel-tabel {@code android.provider.ContactsContract.StreamItems} dan 1825 {@code android.provider.ContactsContract.StreamItemPhotos} 1826 mengelola data yang masuk dari jaringan sosial. Anda bisa menulis adaptor sinkronisasi yang menambahkan data aliran 1827 dari jaringan Anda sendiri ke tabel-tabel ini, atau Anda bisa membaca data aliran dari tabel-tabel ini dan 1828 menampilkannya dalam aplikasi sendiri, atau keduanya. Dengan fitur-fitur ini, layanan dan aplikasi 1829 jaringan sosial Anda bisa diintegrasikan ke dalam pengalaman jaringan sosial Android. 1830 </p> 1831 <h3 id="StreamText">Teks aliran sosial</h3> 1832 <p> 1833 Item aliran selalu dikaitkan dengan kontak mentah. 1834 {@code android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID} menautkan ke 1835 nilai <code>_ID</code> untuk kontak mentah. Tipe akun dan nama akun kontak 1836 mentah juga disimpan dalam baris item aliran. 1837 </p> 1838 <p> 1839 Simpanlah data dari aliran Anda dalam kolom-kolom berikut: 1840 </p> 1841 <dl> 1842 <dt> 1843 {@code android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_TYPE} 1844 </dt> 1845 <dd> 1846 <strong>Diperlukan.</strong> Tipe akun pengguna untuk kontak mentah yang dikaitkan dengan 1847 item aliran ini. Ingatlah untuk mengatur nilai ini saat Anda menyisipkan item aliran. 1848 </dd> 1849 <dt> 1850 {@code android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_NAME} 1851 </dt> 1852 <dd> 1853 <strong>Diperlukan.</strong> Nama akun pengguna untuk kontak mentah yang dikaitkan dengan 1854 item aliran ini. Ingatlah untuk mengatur nilai ini saat Anda menyisipkan item aliran. 1855 </dd> 1856 <dt> 1857 Kolom identifier 1858 </dt> 1859 <dd> 1860 <strong>Diperlukan.</strong> Anda harus memasukkan kolom identifier berikut saat 1861 menyisipkan item aliran: 1862 <ul> 1863 <li> 1864 {@code android.provider.ContactsContract.StreamItemsColumns#CONTACT_ID}: 1865 Nilai {@code android.provider.BaseColumns#_ID} kontak yang dikaitkan dengan item aliran 1866 ini. 1867 </li> 1868 <li> 1869 {@code android.provider.ContactsContract.StreamItemsColumns#CONTACT_LOOKUP_KEY}: 1870 Nilai {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} 1871 kontak yang dikaitkan dengan item aliran ini. 1872 </li> 1873 <li> 1874 {@code android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID}: 1875 Nilai {@code android.provider.BaseColumns#_ID} kontak mentah yang dikaitkan dengan item aliran 1876 ini. 1877 </li> 1878 </ul> 1879 </dd> 1880 <dt> 1881 {@code android.provider.ContactsContract.StreamItemsColumns#COMMENTS} 1882 </dt> 1883 <dd> 1884 Opsional. Menyimpan informasi rangkuman yang bisa Anda tampilkan di awal item aliran. 1885 </dd> 1886 <dt> 1887 {@code android.provider.ContactsContract.StreamItemsColumns#TEXT} 1888 </dt> 1889 <dd> 1890 Teks item aliran, baik konten yang diposting oleh sumber item, 1891 maupun keterangan beberapa tindakan yang menghasilkan item aliran. Kolom ini bisa berisi 1892 sembarang gambar sumber daya pemformatan dan tertanam yang bisa dirender oleh 1893 {@link android.text.Html#fromHtml(String) fromHtml()}. Penyedia bisa memotong atau 1894 menghapus konten yang panjang, tetapi penyedia akan mencoba menghindari memutus tag. 1895 </dd> 1896 <dt> 1897 {@code android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP} 1898 </dt> 1899 <dd> 1900 String teks berisi waktu item aliran yang disisipkan atau diperbarui, berupa 1901 <em>milidetik</em> sejak waktu patokan. Aplikasi yang menyisipkan atau memperbarui item aliran 1902 bertanggung jawab memelihara kolom ini; aplikasi tidak dipelihara secara otomatis oleh 1903 Penyedia Kontak. 1904 </dd> 1905 </dl> 1906 <p> 1907 Untuk menampilkan informasi pengidentifikasi item aliran Anda, gunakan 1908 {@code android.provider.ContactsContract.StreamItemsColumns#RES_ICON}, 1909 {@code android.provider.ContactsContract.StreamItemsColumns#RES_LABEL}, dan 1910 {@code android.provider.ContactsContract.StreamItemsColumns#RES_PACKAGE} untuk menautkan ke sumber daya 1911 dalam aplikasi Anda. 1912 </p> 1913 <p> 1914 Tabel {@code android.provider.ContactsContract.StreamItems} juga berisi kolom-kolom 1915 {@code android.provider.ContactsContract.StreamItemsColumns#SYNC1} hingga 1916 {@code android.provider.ContactsContract.StreamItemsColumns#SYNC4} untuk penggunaan eksklusif oleh 1917 adaptor sinkronisasi. 1918 </p> 1919 <h3 id="StreamPhotos">Foto aliran sosial</h3> 1920 <p> 1921 Tabel {@code android.provider.ContactsContract.StreamItemPhotos} menyimpan foto-foto yang dikaitkan 1922 dengan item aliran. Kolom 1923 {@code android.provider.ContactsContract.StreamItemPhotosColumns#STREAM_ITEM_ID} tabel ini 1924 menautkan ke nilai dalam kolom {@code android.provider.BaseColumns#_ID} 1925 tabel {@code android.provider.ContactsContract.StreamItems}. Acuan foto disimpan dalam 1926 tabel pada kolom-kolom ini: 1927 </p> 1928 <dl> 1929 <dt> 1930 Kolom {@code android.provider.ContactsContract.StreamItemPhotos#PHOTO} (BLOB). 1931 </dt> 1932 <dd> 1933 Representasi biner foto, yang diubah ukurannya oleh penyedia untuk penyimpanan dan tampilan. 1934 Kolom ini tersedia untuk kompatibilitas ke belakang dengan versi Penyedia Kontak 1935 sebelumnya yang menggunakannya untuk menyimpan foto. Akan tetapi, pada versi saat ini 1936 Anda tidak boleh menggunakan kolom ini untuk menyimpan foto. Sebagai gantinya, gunakan 1937 {@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID} atau 1938 {@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI} (keduanya 1939 dijelaskan dalam poin-poin berikut) untuk menyimpan foto di file. Kolom ini sekarang 1940 berisi thumbnail foto, yang tersedia untuk dibaca. 1941 </dd> 1942 <dt> 1943 {@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID} 1944 </dt> 1945 <dd> 1946 Identifier numerik foto untuk kontak mentah. Tambahkan nilai ini ke konstanta 1947 {@link android.provider.ContactsContract.DisplayPhoto#CONTENT_URI DisplayPhoto.CONTENT_URI} 1948 untuk mendapatkan URI konten yang menunjuk ke satu file foto, kemudian panggil 1949 {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String) 1950 openAssetFileDescriptor()} untuk mendapatkan handle ke file foto. 1951 </dd> 1952 <dt> 1953 {@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI} 1954 </dt> 1955 <dd> 1956 URI konten menunjuk langsung ke file foto untuk foto yang diwakili oleh baris ini. 1957 Panggillah {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String) 1958 openAssetFileDescriptor()} dengan URI ini untuk mendapatkan handle ke file foto. 1959 </dd> 1960 </dl> 1961 <h3 id="SocialStreamTables">Menggunakan tabel aliran sosial</h3> 1962 <p> 1963 Tabel-tabel ini sama fungsinya dengan tabel-tabel utama lainnya dalam Penyedia Kontak, kecuali: 1964 </p> 1965 <ul> 1966 <li> 1967 Tabel-tabel ini memerlukan izin akses tambahan. Untuk membaca dari tabel, aplikasi Anda 1968 harus memiliki izin {@code android.Manifest.permission#READ_SOCIAL_STREAM}. Untuk memodifikasi 1969 tabel, aplikasi Anda harus memiliki izin 1970 {@code android.Manifest.permission#WRITE_SOCIAL_STREAM}. 1971 </li> 1972 <li> 1973 Untuk tabel {@code android.provider.ContactsContract.StreamItems}, jumlah baris 1974 yang disimpan bagi setiap kontak mentah adalah terbatas. Setelah batasnya tercapai, 1975 Penyedia Kontak akan membuat ruang untuk baris item aliran baru dengan menghapus secara otomatis 1976 baris yang memiliki 1977 {@code android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP} terlama. Untuk mendapatkan 1978 batas, keluarkan query ke URI konten 1979 {@code android.provider.ContactsContract.StreamItems#CONTENT_LIMIT_URI}. Anda bisa membiarkan 1980 semua argumen selain URI konten diatur ke <code>null</code>. Query 1981 menghasilkan sebuah Kursor yang berisi baris tunggal, dengan kolom tunggal 1982 {@code android.provider.ContactsContract.StreamItems#MAX_ITEMS}. 1983 </li> 1984 </ul> 1985 1986 <p> 1987 Kelas {@code android.provider.ContactsContract.StreamItems.StreamItemPhotos} mendefinisikan 1988 subtabel {@code android.provider.ContactsContract.StreamItemPhotos} yang berisi 1989 baris foto untuk satu item aliran. 1990 </p> 1991 <h3 id="SocialStreamInteraction">Interaksi aliran sosial</h3> 1992 <p> 1993 Data aliran sosial yang dikelola oleh Penyedia Kontak, bersama aplikasi kontak 1994 perangkat, menawarkan cara andal untuk menghubungkan sistem jaringan sosial Anda 1995 dengan kontak yang ada. Tersedia fitur-fitur berikut: 1996 </p> 1997 <ul> 1998 <li> 1999 Dengan menyinkronkan layanan jaringan sosial ke Penyedia Kontak dengan adaptor 2000 sinkronisasi, Anda bisa mengambil aktivitas terbaru untuk kontak pengguna dan menyimpannya dalam tabel-tabel 2001 {@code android.provider.ContactsContract.StreamItems} dan 2002 {@code android.provider.ContactsContract.StreamItemPhotos} untuk digunakan nanti. 2003 </li> 2004 <li> 2005 Selain sinkronisasi rutin, Anda bisa memicu adaptor sinkronisasi agar mengambil 2006 data tambahan bila pengguna memilih sebuah kontak untuk ditampilkan. Hal ini memungkinkan adaptor sinkronisasi Anda 2007 mengambil foto resolusi tinggi dan item aliran terbaru untuk kontak. 2008 </li> 2009 <li> 2010 Dengan mendaftarkan pemberitahuan pada aplikasi kontak perangkat dan Penyedia Kontak, 2011 Anda bisa <em>menerima</em> intent saat kontak ditampilkan, dan pada saat itu 2012 memperbarui status kontak dari layanan Anda. Pendekatan ini mungkin lebih cepat dan menggunakan 2013 bandwidth lebih sedikit daripada melakukan sinkronisasi penuh dengan adaptor sinkronisasi. 2014 </li> 2015 <li> 2016 Pengguna bisa menambahkan kontak ke layanan jaringan sosial Anda sambil melihat kontak 2017 dalam aplikasi kontak perangkat. Anda mengaktifkannya dengan fitur "invite contact", 2018 yang Anda aktifkan dengan kombinasi aktivitas yang menambahkan kontak yang ada ke jaringan 2019 Anda, dan file XML yang menyediakan aplikasi kontak perangkat dan 2020 Penyedia Kontak dengan detail aplikasi Anda. 2021 </li> 2022 </ul> 2023 <p> 2024 Sinkronisasi rutin item aliran dengan Penyedia Kontak sama dengan 2025 sinkronisasi lainnya. Untuk mengetahui selengkapnya tentang sinkronisasi, lihat bagian 2026 <a href="#SyncAdapters">Adaptor Sinkronisasi Penyedia Kontak</a>. Mendaftarkan pemberitahuan dan 2027 mengundang kontak dibahas dalam dua bagian berikutnya. 2028 </p> 2029 <h4>Pendaftaran untuk menangani tampilan jaringan sosial</h4> 2030 <p> 2031 Untuk mendaftarkan adaptor sinkronisasi agar menerima pemberitahuan saat pengguna menampilkan kontak 2032 yang dikelola oleh adaptor sinkronisasi Anda: 2033 </p> 2034 <ol> 2035 <li> 2036 Buat file yang bernama <code>contacts.xml</code> dalam direktori <code>res/xml/</code> 2037 proyek Anda. Jika sudah memiliki file ini, langkah ini boleh dilewati. 2038 </li> 2039 <li> 2040 Dalam file ini, tambahkan elemen 2041 <code><ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"></code>. 2042 Jika elemen ini sudah ada, langkah ini boleh dilewati. 2043 </li> 2044 <li> 2045 Untuk mendaftarkan layanan yang diberitahukan saat pengguna membuka halaman detail kontak dalam 2046 aplikasi kontak perangkat, tambahkan atribut 2047 <code>viewContactNotifyService="<em>serviceclass</em>"</code> ke elemen, dengan 2048 <code><em>serviceclass</em></code> sebagai nama kelas mutlak (fully qualified) dari layanan 2049 yang seharusnya menerima intent dari aplikasi kontak perangkat. Untuk layanan 2050 notifier, gunakan kelas yang memperluas {@link android.app.IntentService}, guna memudahkan layanan 2051 untuk menerima intent. Data dalam intent yang masuk berisi URI konten dari kontak 2052 mentah yang diklik pengguna. Untuk layanan notifier, Anda bisa mengikatnya ke kemudian memanggil 2053 adaptor sinkronisasi Anda untuk memperbarui data bagi kontak mentah. 2054 </li> 2055 </ol> 2056 <p> 2057 Untuk mendaftarkan aktivitas agar dipanggil saat pengguna mengklik item aliran atau foto atau keduanya: 2058 </p> 2059 <ol> 2060 <li> 2061 Buat file yang bernama <code>contacts.xml</code> dalam direktori <code>res/xml/</code> 2062 proyek Anda. Jika sudah memiliki file ini, langkah ini boleh dilewati. 2063 </li> 2064 <li> 2065 Dalam file ini, tambahkan elemen 2066 <code><ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"></code>. 2067 Jika elemen ini sudah ada, langkah ini boleh dilewati. 2068 </li> 2069 <li> 2070 Untuk mendaftarkan salah satu aktivitas Anda guna menangani klik oleh pengguna pada item aliran dalam 2071 aplikasi kontak perangkat, tambahkan atribut 2072 <code>viewStreamItemActivity="<em>activityclass</em>"</code> ke elemen, dengan 2073 <code><em>activityclass</em></code> sebagai nama kelas mutlak (fully-qualified) dari aktivitas 2074 yang harus menerima intent dari aplikasi kontak perangkat. 2075 </li> 2076 <li> 2077 Untuk mendaftarkan salah satu aktivitas Anda guna menangani klik oleh pengguna pada foto aliran dalam 2078 aplikasi kontak perangkat, tambahkan atribut 2079 <code>viewStreamItemPhotoActivity="<em>activityclass</em>"</code> ke elemen, dengan 2080 <code><em>activityclass</em></code> adalah kelas nama mutlak aktivitas 2081 yang harus menerima intent dari aplikasi kontak perangkat. 2082 </li> 2083 </ol> 2084 <p> 2085 Elemen <code><ContactsAccountType></code> dijelaskan lebih detail di 2086 bagian <a href="#SocialStreamAcctType">Elemen <ContactsAccountType></a>. 2087 </p> 2088 <p> 2089 Intent yang masuk berisi URI konten dari materi atau foto yang diklik pengguna. 2090 Untuk mendapatkan aktivitas terpisah bagi item teks dan foto, gunakan kedua atribut dalam file yang sama. 2091 </p> 2092 <h4>Berinteraksi dengan layanan jaringan sosial Anda</h4> 2093 <p> 2094 Pengguna tidak harus meninggalkan aplikasi perangkat kontak untuk mengundang kontak ke situs 2095 jaringan sosial Anda. Sebagai gantinya, Anda bisa meminta aplikasi kontak perangkat mengirimkan intent untuk mengundang 2096 kontak ke salah satu aktivitas Anda. Untuk mempersiapkannya: 2097 </p> 2098 <ol> 2099 <li> 2100 Buat file yang bernama <code>contacts.xml</code> dalam direktori <code>res/xml/</code> 2101 proyek Anda. Jika sudah memiliki file ini, langkah ini boleh dilewati. 2102 </li> 2103 <li> 2104 Dalam file ini, tambahkan elemen 2105 <code><ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"></code>. 2106 Jika elemen ini sudah ada, langkah ini boleh dilewati. 2107 </li> 2108 <li> 2109 Tambahkan atribut-atribut berikut: 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 Nilai <code><em>activityclass</em></code> adalah nama kelas mutlak 2117 aktivitas yang harus menerima intent ini. Nilai <code><em>invite_action_label</em></code> 2118 adalah string teks yang ditampilkan dalam menu <strong>Add Connection</strong> dalam 2119 aplikasi kontak perangkat. 2120 </li> 2121 </ol> 2122 <p class="note"> 2123 <strong>Catatan:</strong> <code>ContactsSource</code> adalah nama tag yang sudah usang untuk 2124 <code>ContactsAccountType</code>. 2125 </p> 2126 <h3 id="ContactsFile">Acuan contacts.xml</h3> 2127 <p> 2128 File <code>contacts.xml</code> berisi elemen XML yang mengontrol interaksi adaptor sinkronisasi 2129 Anda dan aplikasi dengan aplikasi kontak dan Penyedia Kontak. Elemen-elemen ini 2130 dijelaskan di bagian-bagian selanjutnya. 2131 </p> 2132 <h4 id="SocialStreamAcctType">Elemen <ContactsAccountType></h4> 2133 <p> 2134 Elemen <code><ContactsAccountType></code> mengontrol interaksi aplikasi 2135 Anda dengan aplikasi kontak. Sintaksnya adalah sebagai berikut: 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>dimuat dalam:</strong> 2150 </p> 2151 <p> 2152 <code>res/xml/contacts.xml</code> 2153 </p> 2154 <p> 2155 <strong>bisa berisi:</strong> 2156 </p> 2157 <p> 2158 <strong><code><ContactsDataKind></code></strong> 2159 </p> 2160 <p> 2161 <strong>Keterangan:</strong> 2162 </p> 2163 <p> 2164 Mendeklarasikan komponen Android dan label UI yang memungkinkan pengguna mengundang salah satu kontak ke 2165 jaringan sosial, memberi tahu pengguna bila salah satu aliran jaringan sosial diperbarui, dan 2166 seterusnya. 2167 </p> 2168 <p> 2169 Perhatikan bahwa awalan atribut <code>android:</code> tidak perlu untuk atribut-atribut 2170 <code><ContactsAccountType></code>. 2171 </p> 2172 <p> 2173 <strong>Atribut:</strong> 2174 </p> 2175 <dl> 2176 <dt>{@code inviteContactActivity}</dt> 2177 <dd> 2178 Nama kelas mutlak aktivitas dalam aplikasi yang Anda ingin 2179 aktifkan bila pengguna memilih <strong>Add connection</strong> dari aplikasi kontak 2180 perangkat. 2181 </dd> 2182 <dt>{@code inviteContactActionLabel}</dt> 2183 <dd> 2184 String teks yang ditampilkan untuk aktivitas yang ditetapkan dalam 2185 {@code inviteContactActivity}, dalam menu <strong>Add connection</strong>. 2186 Misalnya, Anda bisa menggunakan string "Ikuti di jaringan saya". Anda bisa menggunakan identifier sumber daya 2187 string untuk tabel ini. 2188 </dd> 2189 <dt>{@code viewContactNotifyService}</dt> 2190 <dd> 2191 Nama kelas mutlak layanan dalam aplikasi Anda yang harus menerima 2192 pemberitahuan saat pengguna menampilkan kontak. Pemberitahuan ini dikirimkan oleh aplikasi kontak 2193 perangkat; hal ini memungkinkan aplikasi Anda menunda operasi yang banyak memproses data 2194 hingga dibutuhkan. Misalnya, aplikasi Anda bisa merespons pemberitahuan ini 2195 dengan membaca dalam dan menampilkan foto resolusi tinggi kontak dan item aliran sosial 2196 terbaru. Fitur ini dijelaskan lebih detail di bagian 2197 <a href="#SocialStreamInteraction">Interaksi aliran sosial</a>. Anda bisa melihat 2198 contoh layanan pemberitahuan dalam file <code>NotifierService.java</code> dalam contoh aplikasi 2199 <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">Sample Sync Adapter</a>. 2200 2201 </dd> 2202 <dt>{@code viewGroupActivity}</dt> 2203 <dd> 2204 Nama kelas mutlak aktivitas dalam aplikasi yang bisa menampilkan 2205 informasi grup. Bila pengguna mengklik label grup dalam aplikasi 2206 kontak perangkat, UI aktivitas ini akan ditampilkan. 2207 </dd> 2208 <dt>{@code viewGroupActionLabel}</dt> 2209 <dd> 2210 Label yang ditampilkan aplikasi kontak untuk kontrol UI yang memungkinkan 2211 pengguna melihat grup dalam aplikasi Anda. 2212 <p> 2213 Misalnya, jika Anda menginstal aplikasi Google+ di perangkat dan menyinkronkan 2214 Google+ dengan aplikasi kontak, Anda akan melihat lingkaran Google+ tercantum sebagai grup 2215 dalam tab <strong>Groups</strong> aplikasi kontak Anda. Jika Anda mengklik 2216 lingkaran Google+, Anda akan melihat orang-orang di lingkaran itu tercantum sebagai satu "grup". Di atas 2217 tampilan, Anda akan melihat ikon Google+; jika mengklik ikon itu, kontrol akan beralih ke 2218 aplikasi Google+. Aplikasi kontak melakukan ini dengan 2219 {@code viewGroupActivity}, yang menggunakan ikon Google+ sebagai nilai 2220 {@code viewGroupActionLabel}. 2221 </p> 2222 <p> 2223 Identifier sumber daya string diperbolehkan untuk atribut ini. 2224 </p> 2225 </dd> 2226 <dt>{@code viewStreamItemActivity}</dt> 2227 <dd> 2228 Nama kelas mutlak aktivitas dalam aplikasi Anda 2229 yang diluncurkan aplikasi kontak perangkat bila pengguna mengklik item aliran untuk kontak mentah. 2230 </dd> 2231 <dt>{@code viewStreamItemPhotoActivity}</dt> 2232 <dd> 2233 Nama kelas mutlak aktivitas yang diluncurkan 2234 aplikasi kontak perangkat bila pengguna mengklik foto dalam item aliran 2235 untuk kontak mentah. 2236 </dd> 2237 </dl> 2238 <h4 id="SocialStreamDataKind">Elemen <ContactsDataKind></h4> 2239 <p> 2240 Elemen <code><ContactsDataKind></code> mengontrol tampilan baris data custom 2241 aplikasi Anda dalam UI aplikasi kontak. Sintaksnya adalah sebagai berikut: 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>dimuat dalam:</strong> 2252 </p> 2253 <code><ContactsAccountType></code> 2254 <p> 2255 <strong>Keterangan:</strong> 2256 </p> 2257 <p> 2258 Gunakan elemen ini untuk memerintahkan aplikasi kontak agar menampilkan konten baris data custom sebagai 2259 bagian dari detail kontak mentah. Setiap elemen anak <code><ContactsDataKind></code> 2260 <code><ContactsAccountType></code> mewakili tipe baris data custom yang 2261 ditambahkan adaptor sinkronisasi Anda ke tabel {@link android.provider.ContactsContract.Data}. Tambahkan satu 2262 elemen <code><ContactsDataKind></code> untuk setiap tipe MIME custom yang Anda gunakan. Anda tidak harus 2263 menambahkan elemen jika Anda memiliki baris data custom yang datanya tidak ingin ditampilkan. 2264 </p> 2265 <p> 2266 <strong>Atribut:</strong> 2267 </p> 2268 <dl> 2269 <dt>{@code android:mimeType}</dt> 2270 <dd> 2271 Tipe MIME custom yang telah Anda definisikan untuk salah satu tipe baris data custom dalam 2272 tabel {@link android.provider.ContactsContract.Data}. Misalnya, nilai 2273 <code>vnd.android.cursor.item/vnd.example.locationstatus</code> bisa berupa tipe MIME 2274 custom untuk baris data yang mencatat lokasi kontak yang terakhir diketahui. 2275 </dd> 2276 <dt>{@code android:icon}</dt> 2277 <dd> 2278 2279 <a href="{@docRoot}guide/topics/resources/drawable-resource.html">Sumber daya drawable</a> 2280 Android yang ditampilkan aplikasi kontak di samping data Anda. Gunakan ini untuk menunjukkan kepada 2281 pengguna bahwa data berasal dari layanan Anda. 2282 </dd> 2283 <dt>{@code android:summaryColumn}</dt> 2284 <dd> 2285 Nama kolom untuk yang pertama dari dua nilai yang diambil dari baris data. Nilai 2286 ditampilkan sebagai baris pertama entri untuk baris data ini. Baris pertama 2287 dimaksudkan untuk digunakan sebagai rangkuman data, tetapi itu bersifat opsional. Lihat juga 2288 <a href="#detailColumn">android:detailColumn</a>. 2289 </dd> 2290 <dt>{@code android:detailColumn}</dt> 2291 <dd> 2292 Nama kolom untuk yang kedua dari dua nilai yang diambil dari baris data. Nilai 2293 ditampilkan sebagai baris kedua entri untuk baris data ini. Lihat juga 2294 {@code android:summaryColumn}. 2295 </dd> 2296 </dl> 2297 <h2 id="AdditionalFeatures">Fitur Tambahan Penyedia Kontak</h2> 2298 <p> 2299 Di samping fitur-fitur utama yang dijelaskan di bagian sebelumnya, Penyedia Kontak menawarkan 2300 fitur-fitur berguna ini untuk digunakan bersama data kontak: 2301 </p> 2302 <ul> 2303 <li>Grup kontak</li> 2304 <li>Fitur foto</li> 2305 </ul> 2306 <h3 id="Groups">Grup kontak</h3> 2307 <p> 2308 Penyedia Kontak secara opsional bisa melabeli kumpulan kontak terkait dengan data 2309 <strong>grup</strong>. Jika server yang dikaitkan dengan akun pengguna 2310 ingin mempertahankan grup, adaptor sinkronisasi untuk tipe akun dari akun itu harus mentransfer 2311 data grup antara Penyedia Kontak dan server. Bila pengguna menambahkan kontak baru ke 2312 server, kemudian memasukkan kontak ini dalam grup baru, adaptor sinkronisasi harus menambahkan grup baru 2313 ke tabel {@link android.provider.ContactsContract.Groups}. Grup atau grup-grup yang memiliki kontak 2314 disimpan dalam tabel {@link android.provider.ContactsContract.Data}, dengan menggunakan 2315 tipe MIME {@link android.provider.ContactsContract.CommonDataKinds.GroupMembership}. 2316 </p> 2317 <p> 2318 Jika Anda mendesain adaptor sinkronisasi yang akan menambahkan data kontak mentah dari 2319 server ke Penyedia Kontak, dan Anda tidak menggunakan grup, maka Anda harus memberi tahu 2320 penyedia itu agar membuat data Anda terlihat. Dalam kode yang dijalankan bila pengguna menambahkan akun 2321 ke perangkat, perbarui baris {@link android.provider.ContactsContract.Settings} 2322 yang ditambahkan Penyedia Kontak untuk akunnya. Dalam baris ini, atur nilai kolom 2323 {@link android.provider.ContactsContract.SettingsColumns#UNGROUPED_VISIBLE 2324 Settings.UNGROUPED_VISIBLE} ke 1. Bila melakukannya, Penyedia Kontak akan selalu 2325 membuat data kontak Anda terlihat, meskipun Anda tidak menggunakan grup. 2326 </p> 2327 <h3 id="Photos">Foto kontak</h3> 2328 <p> 2329 Tabel {@link android.provider.ContactsContract.Data} menyimpan foto sebagai baris dengan tipe MIME 2330 {@link android.provider.ContactsContract.CommonDataKinds.Photo#CONTENT_ITEM_TYPE 2331 Photo.CONTENT_ITEM_TYPE}. Kolom 2332 {@link android.provider.ContactsContract.RawContactsColumns#CONTACT_ID} baris yang ditautkan ke 2333 kolom {@code android.provider.BaseColumns#_ID} kontak mentah yang memiliki kolom itu. 2334 Kelas {@link android.provider.ContactsContract.Contacts.Photo} mendefinisikan subtabel 2335 {@link android.provider.ContactsContract.Contacts} yang berisi informasi foto untuk foto 2336 utama kontak, yang merupakan foto utama dari kontak mentah utama kontak itu. Demikian pula, 2337 kelas {@link android.provider.ContactsContract.RawContacts.DisplayPhoto} mendefinisikan subtabel 2338 {@link android.provider.ContactsContract.RawContacts} yang berisi informasi foto untuk 2339 foto utama kontak mentah. 2340 </p> 2341 <p> 2342 Dokumentasi acuan untuk {@link android.provider.ContactsContract.Contacts.Photo} dan 2343 {@link android.provider.ContactsContract.RawContacts.DisplayPhoto} berisi contoh-contoh 2344 pengambilan informasi foto. Tidak ada kelas praktis untuk mengambil 2345 thumbnail utama kontak mentah, tetapi Anda bisa mengirim query ke 2346 tabel {@link android.provider.ContactsContract.Data}, dengan memilih 2347 {@code android.provider.BaseColumns#_ID} kontak mentah, 2348 {@link android.provider.ContactsContract.CommonDataKinds.Photo#CONTENT_ITEM_TYPE 2349 Photo.CONTENT_ITEM_TYPE}, dan kolom {@link android.provider.ContactsContract.Data#IS_PRIMARY} 2350 untuk menemukan baris foto utama kontak mentah. 2351 </p> 2352 <p> 2353 Data aliran sosial untuk seseorang bisa juga disertai foto. Data ini disimpan dalam 2354 tabel {@code android.provider.ContactsContract.StreamItemPhotos}, yang dijelaskan lebih detail 2355 di bagian <a href="#StreamPhotos">Foto aliran sosial</a>. 2356 </p> 2357