Home | History | Annotate | Download | only in providers
      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         &lt;uses-permission&gt;</a></code> sebagai
    569         <code>&lt;uses-permission android:name="android.permission.READ_CONTACTS"&gt;</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         &lt;uses-permission&gt;</a></code> sebagai
    577         <code>&lt;uses-permission android:name="android.permission.WRITE_CONTACTS"&gt;</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 &#64;Override
    886 public Loader&lt;Cursor&gt; onCreateLoader(int id, Bundle args) {
    887 
    888     /*
    889      * Sets the columns to retrieve.
    890      * RAW_CONTACT_ID is included to identify the raw contact associated with the data row.
    891      * DATA1 contains the first column in the data row (usually the most important one).
    892      * MIMETYPE indicates the type of data in the data row.
    893      */
    894     String[] projection =
    895         {
    896             ContactsContract.Contacts.Entity.RAW_CONTACT_ID,
    897             ContactsContract.Contacts.Entity.DATA1,
    898             ContactsContract.Contacts.Entity.MIMETYPE
    899         };
    900 
    901     /*
    902      * Sorts the retrieved cursor by raw contact id, to keep all data rows for a single raw
    903      * contact collated together.
    904      */
    905     String sortOrder =
    906             ContactsContract.Contacts.Entity.RAW_CONTACT_ID +
    907             " ASC";
    908 
    909     /*
    910      * Returns a new CursorLoader. The arguments are similar to
    911      * ContentResolver.query(), except for the Context argument, which supplies the location of
    912      * the ContentResolver to use.
    913      */
    914     return new CursorLoader(
    915             getApplicationContext(),  // The activity's context
    916             mContactUri,              // The entity content URI for a single contact
    917             projection,               // The columns to retrieve
    918             null,                     // Retrieve all the raw contacts and their data rows.
    919             null,                     //
    920             sortOrder);               // Sort by the raw contact ID.
    921 }
    922 </pre>
    923 <p>
    924     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&lt;ContentProviderOperation&gt; ops =
   1070             new ArrayList&lt;ContentProviderOperation&gt;();
   1071 
   1072     /*
   1073      * Creates a new raw contact with its account type (server type) and account name
   1074      * (user's account). Remember that the display name is not stored in this row, but in a
   1075      * StructuredName data row. No other data is required.
   1076      */
   1077     ContentProviderOperation.Builder op =
   1078             ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
   1079             .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType())
   1080             .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName());
   1081 
   1082     // Builds the operation and adds it to the array of operations
   1083     ops.add(op.build());
   1084 </pre>
   1085 <p>
   1086     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&lt;Cursor&gt; loader, Cursor cursor) {
   1274 
   1275     // Gets the raw contact's _ID and VERSION values
   1276     mRawContactID = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID));
   1277     mVersion = cursor.getInt(cursor.getColumnIndex(SyncColumns.VERSION));
   1278 }
   1279 
   1280 ...
   1281 
   1282 // Sets up a Uri for the assert operation
   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&lt;ContentProviderOperationg&gt;;
   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&lt;ContentValues&gt; contactData = new ArrayList&lt;ContentValues&gt;();
   1497 
   1498 
   1499 /*
   1500  * Defines the raw contact row
   1501  */
   1502 
   1503 // Sets up the row as a ContentValues object
   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>&lt;ContactsAccountType&gt;</code> dan satu atau beberapa elemen anak
   1621     <code>&lt;ContactsDataKind&gt;</code>. Hal ini dijelaskan lebih detail di
   1622     bagian <a href="#SocialStreamDataKind"><code>&lt;ContactsDataKind&gt; 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>&lt;<a href="{@docRoot}guide/topics/manifest/service-element.html">service</a>&gt;</code>
   1795             di manifes aplikasi. Elemen-elemen ini
   1796             berisi
   1797 <code>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</code>
   1798 elemen anak yang menyediakan data tertentu ke
   1799             sistem:
   1800             <ul>
   1801                 <li>
   1802                     Elemen
   1803 <code>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</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>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</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>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</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>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</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>&lt;ContactsAccountType&gt;</code> dijelaskan lebih detail di
   2086     bagian <a href="#SocialStreamAcctType">Elemen &lt;ContactsAccountType&gt;</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>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</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="&#64;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 &lt;ContactsAccountType&gt;</h4>
   2133 <p>
   2134     Elemen <code>&lt;ContactsAccountType&gt;</code> mengontrol interaksi aplikasi
   2135     Anda dengan aplikasi kontak. Sintaksnya adalah sebagai berikut:
   2136 </p>
   2137 <pre>
   2138 &lt;ContactsAccountType
   2139         xmlns:android="http://schemas.android.com/apk/res/android"
   2140         inviteContactActivity="<em>activity_name</em>"
   2141         inviteContactActionLabel="<em>invite_command_text</em>"
   2142         viewContactNotifyService="<em>view_notify_service</em>"
   2143         viewGroupActivity="<em>group_view_activity</em>"
   2144         viewGroupActionLabel="<em>group_action_text</em>"
   2145         viewStreamItemActivity="<em>viewstream_activity_name</em>"
   2146         viewStreamItemPhotoActivity="<em>viewphotostream_activity_name</em>"&gt;
   2147 </pre>
   2148 <p>
   2149     <strong>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>&lt;ContactsDataKind&gt;</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>&lt;ContactsAccountType&gt;</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 &lt;ContactsDataKind&gt;</h4>
   2239 <p>
   2240     Elemen <code>&lt;ContactsDataKind&gt;</code> mengontrol tampilan baris data custom
   2241     aplikasi Anda dalam UI aplikasi kontak. Sintaksnya adalah sebagai berikut:
   2242 </p>
   2243 <pre>
   2244 &lt;ContactsDataKind
   2245         android:mimeType="<em>MIMEtype</em>"
   2246         android:icon="<em>icon_resources</em>"
   2247         android:summaryColumn="<em>column_name</em>"
   2248         android:detailColumn="<em>column_name</em>"&gt;
   2249 </pre>
   2250 <p>
   2251     <strong>dimuat dalam:</strong>
   2252 </p>
   2253 <code>&lt;ContactsAccountType&gt;</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>&lt;ContactsDataKind&gt;</code>
   2260     <code>&lt;ContactsAccountType&gt;</code> mewakili tipe baris data custom yang
   2261     ditambahkan adaptor sinkronisasi Anda ke tabel {@link android.provider.ContactsContract.Data}. Tambahkan satu
   2262     elemen <code>&lt;ContactsDataKind&gt;</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