• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.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@dataservice.example.com}, pengguna harus menambahkan lebih dahulu "type"
256            akun ({@code com.example.dataservice}) dan "name" akun
257            ({@code becky.smart@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@gmail.com</code></li>
270    <li><code>emilyd@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@gmail.com</code>, membuka
280    Contacts, dan menambahkan "Thomas Higginson". Kemudian, ia masuk ke Gmail sebagai
281    <code>emilyd@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@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@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@gmail.com} (baris kontak mentah untuk Thomas Higginson
311   yang dikaitkan dengan akun Google <code>emilyd@gmail.com</code>) memiliki alamat email rumah
312    <code>thigg@gmail.com</code> dan alamat email kerja
313    <code>thomas.higginson@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
624mProjection = new String[]
625    {
626        Profile._ID,
627        Profile.DISPLAY_NAME_PRIMARY,
628        Profile.LOOKUP_KEY,
629        Profile.PHOTO_THUMBNAIL_URI
630    };
631
632// Retrieves the profile from the Contacts Provider
633mProfileCursor =
634        getContentResolver().query(
635                Profile.CONTENT_URI,
636                mProjection ,
637                null,
638                null,
639                null);
640</pre>
641<p class="note">
642    <strong>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@gmail.com} boleh memiliki id sumber
727                        yang sama dengan kontak mentah "Thomas Higginson" untuk akun
728                        {@code emilyd@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
886public Loader&lt;Cursor&gt; onCreateLoader(int id, Bundle args) {
887
888    /*
889     * Sets the columns to retrieve.
890     * RAW_CONTACT_ID is included to identify the raw contact associated with the data row.
891     * DATA1 contains the first column in the data row (usually the most important one).
892     * MIMETYPE indicates the type of data in the data row.
893     */
894    String[] projection =
895        {
896            ContactsContract.Contacts.Entity.RAW_CONTACT_ID,
897            ContactsContract.Contacts.Entity.DATA1,
898            ContactsContract.Contacts.Entity.MIMETYPE
899        };
900
901    /*
902     * Sorts the retrieved cursor by raw contact id, to keep all data rows for a single raw
903     * contact collated together.
904     */
905    String sortOrder =
906            ContactsContract.Contacts.Entity.RAW_CONTACT_ID +
907            " ASC";
908
909    /*
910     * Returns a new CursorLoader. The arguments are similar to
911     * ContentResolver.query(), except for the Context argument, which supplies the location of
912     * the ContentResolver to use.
913     */
914    return new CursorLoader(
915            getApplicationContext(),  // The activity's context
916            mContactUri,              // The entity content URI for a single contact
917            projection,               // The columns to retrieve
918            null,                     // Retrieve all the raw contacts and their data rows.
919            null,                     //
920            sortOrder);               // Sort by the raw contact ID.
921}
922</pre>
923<p>
924    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.
1043protected void createContactEntry() {
1044    /*
1045     * Gets values from the UI
1046     */
1047    String name = mContactNameEditText.getText().toString();
1048    String phone = mContactPhoneEditText.getText().toString();
1049    String email = mContactEmailEditText.getText().toString();
1050
1051    int phoneType = mContactPhoneTypes.get(
1052            mContactPhoneTypeSpinner.getSelectedItemPosition());
1053
1054    int emailType = mContactEmailTypes.get(
1055            mContactEmailTypeSpinner.getSelectedItemPosition());
1056</pre>
1057<p>
1058    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 */
1273public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor cursor) {
1274
1275    // Gets the raw contact's _ID and VERSION values
1276    mRawContactID = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID));
1277    mVersion = cursor.getInt(cursor.getColumnIndex(SyncColumns.VERSION));
1278}
1279
1280...
1281
1282// Sets up a Uri for the assert operation
1283Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, mRawContactID);
1284
1285// Creates a builder for the assert operation
1286ContentProviderOperation.Builder assertOp = ContentProviderOperation.netAssertQuery(rawContactUri);
1287
1288// Adds the assertions to the assert operation: checks the version and count of rows tested
1289assertOp.withValue(SyncColumns.VERSION, mVersion);
1290assertOp.withExpectedCount(1);
1291
1292// Creates an ArrayList to hold the ContentProviderOperation objects
1293ArrayList ops = new ArrayList&lt;ContentProviderOperationg&gt;;
1294
1295ops.add(assertOp.build());
1296
1297// You would add the rest of your batch operations to "ops" here
1298
1299...
1300
1301// Applies the batch. If the assert fails, an Exception is thrown
1302try
1303    {
1304        ContentProviderResult[] results =
1305                getContentResolver().applyBatch(AUTHORITY, ops);
1306
1307    } catch (OperationApplicationException e) {
1308
1309        // Actions you want to take if the assert operation fails go here
1310    }
1311</pre>
1312<h3 id="Intents">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
1370StructuredPostal.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
1471String name = mContactNameEditText.getText().toString();
1472String phone = mContactPhoneEditText.getText().toString();
1473String email = mContactEmailEditText.getText().toString();
1474
1475String company = mCompanyName.getText().toString();
1476String jobtitle = mJobTitle.getText().toString();
1477
1478// Creates a new intent for sending to the device's contacts application
1479Intent insertIntent = new Intent(ContactsContract.Intents.Insert.ACTION);
1480
1481// Sets the MIME type to the one expected by the insertion activity
1482insertIntent.setType(ContactsContract.RawContacts.CONTENT_TYPE);
1483
1484// Sets the new contact name
1485insertIntent.putExtra(ContactsContract.Intents.Insert.NAME, name);
1486
1487// Sets the new company and job title
1488insertIntent.putExtra(ContactsContract.Intents.Insert.COMPANY, company);
1489insertIntent.putExtra(ContactsContract.Intents.Insert.JOB_TITLE, jobtitle);
1490
1491/*
1492 * Demonstrates adding data rows as an array list associated with the DATA key
1493 */
1494
1495// Defines an array list to contain the ContentValues objects for each row
1496ArrayList&lt;ContentValues&gt; contactData = new ArrayList&lt;ContentValues&gt;();
1497
1498
1499/*
1500 * Defines the raw contact row
1501 */
1502
1503// Sets up the row as a ContentValues object
1504ContentValues rawContactRow = new ContentValues();
1505
1506// Adds the account type and name to the row
1507rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType());
1508rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName());
1509
1510// Adds the row to the array
1511contactData.add(rawContactRow);
1512
1513/*
1514 * Sets up the phone number data row
1515 */
1516
1517// Sets up the row as a ContentValues object
1518ContentValues phoneRow = new ContentValues();
1519
1520// Specifies the MIME type for this data row (all data rows must be marked by their type)
1521phoneRow.put(
1522        ContactsContract.Data.MIMETYPE,
1523        ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
1524);
1525
1526// Adds the phone number and its type to the row
1527phoneRow.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
1528
1529// Adds the row to the array
1530contactData.add(phoneRow);
1531
1532/*
1533 * Sets up the email data row
1534 */
1535
1536// Sets up the row as a ContentValues object
1537ContentValues emailRow = new ContentValues();
1538
1539// Specifies the MIME type for this data row (all data rows must be marked by their type)
1540emailRow.put(
1541        ContactsContract.Data.MIMETYPE,
1542        ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE
1543);
1544
1545// Adds the email address and its type to the row
1546emailRow.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email);
1547
1548// Adds the row to the array
1549contactData.add(emailRow);
1550
1551/*
1552 * Adds the array to the intent's extras. It must be a parcelable object in order to
1553 * travel between processes. The device's contacts app expects its key to be
1554 * Intents.Insert.DATA
1555 */
1556insertIntent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contactData);
1557
1558// Send out the intent to start the device's contacts app in its add contact activity.
1559startActivity(insertIntent);
1560</pre>
1561<h3 id="DataIntegrity">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>
1798elemen 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