• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=連絡先プロバイダ
2@jd:body
3<div id="qv-wrapper">
4<div id="qv">
5<h2>クイックビュー</h2>
6<ul>
7    <li>人の情報に関する Android のリポジトリ。</li>
8    <li>
9        ウェブとの同期。
10    </li>
11    <li>
12        ソーシャル ストリーム データの統合。
13    </li>
14</ul>
15<h2>本書の内容</h2>
16<ol>
17    <li>
18        <a href="#InformationTypes">連絡先プロバイダの構成</a>
19    </li>
20    <li>
21        <a href="#RawContactBasics">未加工連絡先</a>
22    </li>
23    <li>
24        <a href="#DataBasics">データ</a>
25    </li>
26    <li>
27        <a href="#ContactBasics">連絡先</a>
28    </li>
29    <li>
30        <a href="#Sources">同期アダプタからのデータ</a>
31    </li>
32    <li>
33        <a href="#Permissions">必要なパーミッション</a>
34    </li>
35    <li>
36        <a href="#UserProfile">ユーザー プロファイル</a>
37    </li>
38    <li>
39        <a href="#ContactsProviderMetadata">連絡先プロバイダのメタデータ</a>
40    </li>
41    <li>
42        <a href="#Access">連絡先プロバイダへのアクセス</a>
43    <li>
44    </li>
45    <li>
46        <a href="#SyncAdapters">連絡先プロバイダの同期アダプタ</a>
47    </li>
48    <li>
49        <a href="#SocialStream">ソーシャル ストリーム データ</a>
50    </li>
51    <li>
52        <a href="#AdditionalFeatures">連絡先プロバイダの追加機能</a>
53    </li>
54</ol>
55<h2>キークラス</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>関連サンプル</h2>
63<ol>
64    <li>
65        <a href="{@docRoot}resources/samples/ContactManager/index.html">        Contact Manager        </a>
66
67
68    </li>
69    <li>
70        <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">        サンプル同期アダプタ</a>
71
72    </li>
73</ol>
74<h2>関連ドキュメント</h2>
75<ol>
76    <li>
77        <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">        コンテンツ プロバイダの基本        </a>
78
79
80    </li>
81</ol>
82</div>
83</div>
84<p>
85    連絡先プロバイダは、人のデータに関する端末の中央リポジトリを管理する、柔軟で効果的な Android コンポーネントです。
86連絡先プロバイダは、端末の連絡先アプリケーションに表示されるデータのソースであり、さらに独自アプリケーションで連絡先プロバイダのデータにアクセスし、端末とオンライン サービスとの間でデータを転送することもできます。
87
88このプロバイダは幅広いデータソースに対応しており、各人に関してできるだけ多くのデータを管理しようとするため、複雑な構造をしています。
89
90そのため、連絡先プロバイダの API には、データの取得と変更をどちらもやりやすくするクラスやインターフェースが多数用意されています。
91
92
93</p>
94<p>
95    このガイドでは、以下について説明します。
96</p>
97    <ul>
98        <li>
99            プロバイダの基本構造。
100        </li>
101        <li>
102            プロバイダからのデータの取得方法。
103        </li>
104        <li>
105            プロバイダでのデータの変更方法。
106        </li>
107        <li>
108            サーバーから連絡先プロバイダとデータを同期する同期アダプタの作成方法。
109
110        </li>
111    </ul>
112<p>
113    このガイドは、Android のコンテンツ プロバイダの基礎知識がある読者を対象としています。Android のコンテンツ プロバイダについて詳しくは、「<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">コンテンツ プロバイダの基本</a>」をご覧ください。
114
115
116<a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">サンプル同期アダプタ</a> サンプルアプリは、同期アダプタを使用して連絡先プロバイダと Google ウェブ サービスでホストされているサンプル アプリケーションとの間でデータを転送する例です。
117
118
119
120</p>
121<h2 id="InformationTypes">連絡先プロバイダの構成</h2>
122<p>
123    連絡先プロバイダは、Android のコンテンツ プロバイダ コンポーネントです。人に関する 3 種類のデータを保持しており、それぞれがコンテンツ プロバイダによって提供される 1 つのテーブルに対応しています。この構成を図 1 に示します。
124
125
126</p>
127<img src="{@docRoot}images/providers/contacts_structure.png" alt="" height="364" id="figure1" />
128<p class="img-caption">
129  <strong>図 1.</strong> 連絡先プロバイダのテーブル構造。
130</p>
131<p>
132    この 3 つのテーブルは、一般にそれぞれのコントラクト クラス名で呼ばれます。各クラスは、テーブルによって使用されるコンテンツ URI、列名、列の値のための定数を定義しています。
133
134</p>
135<dl>
136    <dt>
137        {@link android.provider.ContactsContract.Contacts} テーブル
138    </dt>
139    <dd>
140        各行は、未加工連絡先の行の集約に基づいて異なる人を表します。
141    </dd>
142    <dt>
143        {@link android.provider.ContactsContract.RawContacts} テーブル
144    </dt>
145    <dd>
146        各行には、ユーザーのアカウントとタイプに固有の、人に関するデータの概要が格納されています。
147    </dd>
148    <dt>
149        {@link android.provider.ContactsContract.Data} テーブル
150    </dt>
151    <dd>
152        各行には、メールアドレスや電話番号など、未加工連絡先の詳細情報が格納されています。
153    </dd>
154</dl>
155<p>
156    {@link android.provider.ContactsContract} に含まれるコントラクト クラスによって表現される他のテーブルは補助テーブルであり、連絡先プロバイダがその操作を管理したり、端末の連絡先アプリや電話アプリの特定機能をサポートしたりするために使用します。
157
158
159</p>
160<h2 id="RawContactBasics">未加工連絡先</h2>
161<p>
162    未加工連絡先は、アカウント タイプとアカウント名の 1 つのペアを使用して得られる人に関するデータです。
163連絡先プロバイダでは、1 人に関するデータのソースとして複数のオンライン サーバーを使用できるため、同じ個人に対して複数の未加工連絡先が許されます。
164
165    未加工連絡先が複数ある場合、ユーザーは同じアカウント タイプの複数のアカウントから取得したその人のデータを組み合わせることができます。
166
167</p>
168<p>
169    未加工連絡先データの大半は、{@link android.provider.ContactsContract.RawContacts} テーブルには格納されません。
170その代わり、{@link android.provider.ContactsContract.Data} テーブルの 1 つまたは複数の行に格納されています。
171各データ行には列 {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID Data.RAW_CONTACT_ID} があり、親 {@link android.provider.ContactsContract.RawContacts} 行の {@code android.provider.BaseColumns#_ID RawContacts._ID} 値が格納されています。
172
173
174
175</p>
176<h3 id="RawContactsColumns">重要な未加工連絡先列</h3>
177<p>
178    表 1 に、{@link android.provider.ContactsContract.RawContacts} の重要な列を示します。
179表の後の注もお読みください。
180</p>
181<p class="table-caption" id="table1">
182    <strong>表 1.</strong> 重要な未加工連絡先列。
183</p>
184<table>
185    <tr>
186        <th scope="col">列名</th>
187        <th scope="col">用途</th>
188        <th scope="col">注</th>
189    </tr>
190    <tr>
191        <td>
192            {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_NAME}
193        </td>
194        <td>
195            この未加工連絡先のソースであるアカウント タイプにおけるアカウント名。
196            たとえば、Google アカウントのアカウント名は、デバイス オーナーの Gmail アドレスのどれかです。
197詳しくは、次の {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_TYPE} の項目をご覧ください。
198
199
200        </td>
201        <td>
202            この名前の形式は、アカウント タイプによって異なります。必ずしもメールアドレスとは限りません。
203
204        </td>
205    </tr>
206    <tr>
207        <td>
208            {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_TYPE}
209        </td>
210        <td>
211            この未加工連絡先のソースであるアカウント タイプ。たとえば、Google アカウントのアカウント タイプは <code>com.google</code> です。
212アカウント タイプは必ず、所有または管理しているドメインのドメイン ID で修飾してください。
213そうすることで、アカウント タイプが確実に一意になります。
214
215        </td>
216        <td>
217            連絡先データを提供するアカウント タイプには、通常、連絡先プロバイダと同期する関連同期アダプタが用意されています。
218
219    </tr>
220    <tr>
221        <td>
222            {@link android.provider.ContactsContract.RawContactsColumns#DELETED}
223        </td>
224        <td>
225            未加工連絡先の「削除済み」フラグ。
226        </td>
227        <td>
228            連絡先プロバイダは、同期アダプタが該当行をサーバーから削除し、最終的にリポジトリから削除するまで、このフラグを基に行を内部的に管理します。
229
230
231        </td>
232    </tr>
233</table>
234<h4>注</h4>
235<p>
236    次に、{@link android.provider.ContactsContract.RawContacts} テーブルに関する重要な注を示します。
237
238</p>
239<ul>
240    <li>
241        未加工連絡先の名前は、{@link android.provider.ContactsContract.RawContacts} の行には格納されません。
242その代わり、{@link android.provider.ContactsContract.Data} テーブルの {@link android.provider.ContactsContract.CommonDataKinds.StructuredName} 行に格納されます。
243
244未加工連絡先は、このタイプの行を {@link android.provider.ContactsContract.Data} テーブルに 1 行だけ持ちます。
245
246    </li>
247    <li>
248        <strong>警告:</strong> 未加工連絡先の行で独自のアカウント データを使用する場合は、まずそれを {@link android.accounts.AccountManager} に登録する必要があります。
249登録するには、ユーザーに対し、アカウントのリストにアカウント タイプとアカウント名を追加するよう求めます。
250そうしないと、連絡先プロバイダによって未加工連絡先の行が自動的に削除されてしまいます。
251
252        <p>
253            たとえば、ドメインが {@code com.example.dataservice} であるウェブベースのサービス用に連絡先データをアプリで管理する場合、そのサービス用のユーザー アカウントが {@code becky.sharp@dataservice.example.com} であれば、そのユーザーが先にそのアカウントの「タイプ」({@code com.example.dataservice})と「名前」({@code becky.smart@dataservice.example.com})を追加しておくことで、アプリが未加工連絡先の行を追加できるようになります。
254
255
256
257
258            この要件については、文書で説明するか、ユーザーにタイプと名前を追加するよう求めるか、あるいはその両方を実施してください。
259アカウントのタイプと名前については、次のセクションで詳しく説明します。
260
261    </li>
262</ul>
263<h3 id="RawContactsExample">未加工連絡先データのソース</h3>
264<p>
265    未加工連絡先の働きを理解するために、「Emily Dickinson」というユーザーについて考えてみましょう。彼女は自分の端末に次の 3 つのアカウントを定義しています。
266
267</p>
268<ul>
269    <li><code>emily.dickinson@gmail.com</code></li>
270    <li><code>emilyd@gmail.com</code></li>
271    <li>Twitter アカウント「belle_of_amherst」</li>
272</ul>
273<p>
274    このユーザーは、[<em>アカウント</em>] の設定でこの 3 つのアカウントすべてについて [<em>連絡先を同期</em>] を有効にしています。
275
276</p>
277<p>
278    Emily Dickinson がブラウザのウィンドウを開き、Gmail に <code>emily.dickinson@gmail.com</code> としてログインし、[連絡先] を開いて「Thomas Higginson」を追加したとしましょう。
279
280後日、彼女が Gmail に <code>emilyd@gmail.com</code> としてログインし、メールを「Thomas Higginson」宛てに送信すると、彼は自動的に連絡先として追加されます。
281
282彼女はまた、Twitter で「colonel_tom」(Thomas Higginson の Twitter ID)をフォローしています。
283
284</p>
285<p>
286    連絡先プロバイダは、この操作の結果として次の 3 行の未加工連絡先を作成します。
287</p>
288<ol>
289    <li>
290        「Thomas Higginson」の、<code>emily.dickinson@gmail.com</code> に関連付けられた未加工連絡先。
291        ユーザー アカウントのタイプは Google です。
292    </li>
293    <li>
294        「Thomas Higginson」の、<code>emilyd@gmail.com</code> に関連付けられた新たな未加工連絡先。
295        ユーザー アカウントのタイプはやはり Google です。名前が前の行とまったく同じなのに新たな未加工連絡先が作成されたのは、この個人が異なるユーザー アカウントに追加されたからです。
296
297
298    </li>
299    <li>
300        「Thomas Higginson」の、「belle_of_amherst」に関連付けられた未加工連絡先。ユーザー アカウントのタイプは Twitter です。
301
302    </li>
303</ol>
304<h2 id="DataBasics">データ</h2>
305<p>
306    前にも説明したように、未加工連絡先のデータは未加工連絡先の <code>_ID</code> 値にリンクされている {@link android.provider.ContactsContract.Data} 行に格納されます。
307
308これにより、1 つの未加工連絡先が同じタイプのデータ(メールアドレスや電話番号など)のインスタンスを複数持つことができます。
309たとえば、{@code emilyd@gmail.com} に対する「Thomas Higginson」(Google アカウント <code>emilyd@gmail.com</code> に関連付けられた、Thomas Higginson の未加工連絡先の行)には、<code>thigg@gmail.com</code> という個人用アドレスと <code>thomas.higginson@gmail.com</code> という仕事用アドレスがあり、連絡先プロバイダはこの 2 つのメールアドレスの行を格納し、両方とも同じ未加工連絡先にリンクします。
310
311
312
313
314
315</p>
316<p>
317    異なるタイプのデータが同じテーブルに格納されることに注目してください。表示名、電話番号、メール、住所、写真、ウェブサイトに関する詳細行はすべて、{@link android.provider.ContactsContract.Data} テーブルにあります。
318
319これを管理しやすくするため、{@link android.provider.ContactsContract.Data} テーブルの一部の行には説明的な名前が、それ以外には一般的な名前がそれぞれ付いています。
320
321説明的な名前が付いた列の内容は、行データのタイプによらず意味が同じなのに対し、一般的な名前が付いた列の内容は、データのタイプによって意味が異なります。
322
323
324</p>
325<h3 id="DescriptiveColumns">説明的な名前の列</h3>
326<p>
327    説明的な名前が付いた列の例をいくつか示します。
328</p>
329<dl>
330    <dt>
331        {@link android.provider.ContactsContract.Data#RAW_CONTACT_ID}
332    </dt>
333    <dd>
334        このデータの、未加工連絡先の <code>_ID</code> 列の値。
335    </dd>
336    <dt>
337        {@link android.provider.ContactsContract.Data#MIMETYPE}
338    </dt>
339    <dd>
340        カスタム MIME タイプで表現した、この行に格納されているデータのタイプ。連絡先プロバイダは、{@link android.provider.ContactsContract.CommonDataKinds} のサブクラスに定義されている MIME タイプを使用します。
341
342これらの MIME タイプはオープンソースで、連絡先プロバイダと連携する任意のアプリケーションまたは同期アダプタで使用できます。
343
344    </dd>
345    <dt>
346        {@link android.provider.ContactsContract.DataColumns#IS_PRIMARY}
347    </dt>
348    <dd>
349        このタイプのデータ行が 1 つの未加工連絡先に対して複数発生する場合、{@link android.provider.ContactsContract.DataColumns#IS_PRIMARY} 列はそのタイプに対するプライマリ データを含むデータ行を示します。
350
351たとえば、ユーザーがある連絡先の電話番号を長押しし、[<strong>デフォルトに設定</strong>] を選択すると、その番号を含む {@link android.provider.ContactsContract.Data} 行の {@link android.provider.ContactsContract.DataColumns#IS_PRIMARY} 列にゼロでない値が設定されます。
352
353
354
355
356    </dd>
357</dl>
358<h3 id="GenericColumns">汎用名の列</h3>
359<p>
360    自由に使用できる <code>DATA1</code> ~ <code>DATA15</code> という 15 個の汎用列の他に、同期アダプタしか使用してはいけない <code>SYNC1</code> ~ <code>SYNC4</code> という 4 個の列があります。
361
362
363汎用名列の定数は、行に指定されているデータのタイプによらず、常に機能します。
364
365</p>
366<p>
367    <code>DATA1</code> 列はインデックス付きです。連絡先プロバイダは常に、この列を、最も頻繁にクエリの対象となるとプロバイダが予想するデータ用の列として使用します。
368たとえば、メールの行では、この列には実際のメールアドレスが格納されます。
369
370</p>
371<p>
372    <code>DATA15</code> は慣例として、写真サムネイルのようなバイナリ ラージ オブジェクト(BLOB)データ用に予約されています。
373
374</p>
375<h3 id="TypeSpecificNames">タイプ固有の列名</h3>
376<p>
377    特定タイプの行に含まれる列に対する作業をやりやすくするため、連絡先プロバイダではタイプ固有の列名定数もあり、たとえば {@link android.provider.ContactsContract.CommonDataKinds} のサブクラスに定義されています。
378
379こうした定数は、同じ列名に異なる定数名を充てて、特定タイプの行に含まれるデータにアクセスしやすくしているだけのものです。
380
381
382</p>
383<p>
384    たとえば、{@link android.provider.ContactsContract.CommonDataKinds.Email} クラスには、MIME タイプが {@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_ITEM_TYPE Email.CONTENT_ITEM_TYPE} である{@link android.provider.ContactsContract.Data} 行向けにタイプ固有の列名定数が定義されています。
385
386
387
388このクラスには、メールアドレス 列用に {@link android.provider.ContactsContract.CommonDataKinds.Email#ADDRESS} という定数が含まれています。
389
390{@link android.provider.ContactsContract.CommonDataKinds.Email#ADDRESS} の実際の値は「data1」で、これはこの列の汎用名と同じです。
391
392
393</p>
394<p class="caution">
395    <strong>警告:</strong> 連絡先プロバイダにあらかじめ定義されている MIME タイプのどれかである行を使用している {@link android.provider.ContactsContract.Data} テーブルには、独自のカスタムデータを追加しないでください。
396
397追加すると、データが失われたり、連絡先プロバイダが誤動作したりすることがあります。
398たとえば、メールアドレスではなくユーザー名が格納されている MIME タイプ {@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_ITEM_TYPE Email.CONTENT_ITEM_TYPE} の行は、列 <code>DATA1</code> には追加しないでください。
399
400
401一方、行に独自のカスタム MIME タイプを使用している場合は、独自のタイプ固有名を定義して列を自由に使用してかまいません。
402
403</p>
404<p>
405    図 2 に、説明的な名前の列とデータ列で {@link android.provider.ContactsContract.Data} 行がどう見えるか、そしてタイプ固有の列名が汎用列名をどう「オーバーレイ」するかを示します。
406
407
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>図 2.</strong> タイプ固有の列名と汎用列名
412</p>
413<h3 id="ColumnMaps">タイプ固有列名が使用されるクラス</h3>
414<p>
415    表 2 に、最もよく用いられるタイプ固有列名クラスを示します。
416</p>
417<p class="table-caption" id="table2">
418  <strong>表 2.</strong> タイプ固有列名が使用されるクラス</p>
419<table>
420  <tr>
421    <th scope="col">対応クラス</th>
422    <th scope="col">データのタイプ</th>
423    <th scope="col">注</th>
424  </tr>
425  <tr>
426    <td>{@link android.provider.ContactsContract.CommonDataKinds.StructuredName}</td>
427    <td>このデータ行に関連付けられている未加工連絡先の名前データ。</td>
428    <td>1 つの未加工連絡先は、この行を 1 行だけ持ちます。</td>
429  </tr>
430  <tr>
431    <td>{@link android.provider.ContactsContract.CommonDataKinds.Photo}</td>
432    <td>このデータ行に関連付けられている未加工連絡先のメインの写真。</td>
433    <td>1 つの未加工連絡先は、この行を 1 行だけ持ちます。</td>
434  </tr>
435  <tr>
436    <td>{@link android.provider.ContactsContract.CommonDataKinds.Email}</td>
437    <td>このデータ行に関連付けられている未加工連絡先のメールレアドレス。</td>
438    <td>1 つの未加工連絡先は複数のメールアドレスを持つことができます。</td>
439  </tr>
440  <tr>
441    <td>{@link android.provider.ContactsContract.CommonDataKinds.StructuredPostal}</td>
442    <td>このデータ行に関連付けられている未加工連絡先の住所。</td>
443    <td>1 つの未加工連絡先は複数の住所を持つことができます。</td>
444  </tr>
445  <tr>
446    <td>{@link android.provider.ContactsContract.CommonDataKinds.GroupMembership}</td>
447    <td>その未加工連絡先を連絡先プロバイダのグループのどれかにリンクする識別子。</td>
448    <td>
449        グループは、アカウント タイプとアカウント名のオプション機能です。詳しくは、<a href="#Groups">連絡先グループ</a>をご覧ください。
450
451    </td>
452  </tr>
453</table>
454<h3 id="ContactBasics">連絡先</h3>
455<p>
456    連絡先プロバイダは、すべてのアカウント タイプとアカウント名にわたって未加工連絡先の行を結び付けて 1 つの<strong>連絡先</strong>を形成します。
457これにより、1 人の人についてユーザーが集めた全データを表示したり変更したりしやすくなります。
458連絡先プロバイダは、新しい連絡先の行の作成と、既存の連絡先の行を使用した未加工連絡先の集約とを管理します。
459アプリケーションと同期アダプタは連絡先の追加はできず、連絡先の行の一部の列は読み取り専用です。
460
461</p>
462<p class="note">
463    <strong>注:</strong> 連絡先を連絡先プロバイダに {@link android.content.ContentResolver#insert(Uri,ContentValues) insert()} を使用して追加しようとすると、{@link java.lang.UnsupportedOperationException} 例外が発生します。
464
465「読み取り専用」になっている列をアップデートしようとしても、そのアップデートは無視されます。
466
467</p>
468<p>
469    連絡先プロバイダは、既存の連絡先と一致しない新しい未加工連絡先が追加されると、それに対して新しい連絡先を作成します。
470また、既存の未加工連絡先のデータが変更され、それまで関連付けられていた連絡先と一致しなくなった場合にも、同じ処理がなされます。
471
472アプリケーションまたは同期アダプタが、既存の連絡先と一致する新しい未加工連絡先を作成すると、その新しい未加工連絡先は既存の連絡先に集約されます。<em></em>
473
474
475</p>
476<p>
477    連絡先プロバイダは、連絡先の行を未加工連絡先とリンクするのに、{@link android.provider.ContactsContract.Contacts Contacts} テーブルの <code>_ID</code> 列を使用します。
478
479未加工連絡先テーブル {@link android.provider.ContactsContract.RawContacts} の <code>CONTACT_ID</code> 列には、未加工連絡先の各行に関連付けられている連絡先の行の <code>_ID</code> 値が格納されます。
480
481
482</p>
483<p>
484    {@link android.provider.ContactsContract.Contacts} テーブルには列 {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} もあり、こちらは連絡先の行への「永久」リンクです。
485
486連絡先プロバイダは連絡先を自動的に管理するため、集約や同期が行われると、それに応じて連絡先の行の {@code android.provider.BaseColumns#_ID} 値が変更される場合があります。
487
488この処理が行われても、コンテンツ URI {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI} と連絡先の {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} の組み合わせは、引き続きその連絡先の行を指すため、{@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} を使用して「お気に入り」の連絡先へのリンクを管理するなどができます。
489
490
491
492
493この列には、{@code android.provider.BaseColumns#_ID} 列の形式と関係のない独自の形式があります。
494
495</p>
496<p>
497    図 3 に、3 つのテーブルの相互関係を示します。
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>図 3.</strong> Contacts、RawContacts、Data の各テーブル間の関係。
502</p>
503<h2 id="Sources">同期アダプタからのデータ</h2>
504<p>
505    ユーザーは端末に連絡先データを直接入力しますが、データはウェブサービスから<strong>同期アダプタ</strong>を経由して連絡先プロバイダにも流れます。同期アダプタは、端末とサービスの間のデータ転送を自動化します。
506
507同期アダフタはシステムの管理下でバックグラウンドで実行され、{@link android.content.ContentResolver} のメソッドを呼び出してデータを管理します。
508
509
510</p>
511<p>
512    Android では、同期アダプタと連携するウェブサービスをアカウント タイプで識別します。
513    各同期アダプタが扱うアカウント タイプは 1 つですが、そのタイプのアカウント名を複数サポートできます。
514アカウント名とアカウント タイプについては、<a href="#RawContactsExample">未加工連絡先データのソース</a>で簡単に説明しています。
515次に、アカウント タイプとアカウント名が同期アダプタやサービスとどのような関係にあるかを詳しく説明します。
516
517</p>
518<dl>
519    <dt>
520        アカウント タイプ
521    </dt>
522    <dd>
523        ユーザーがデータを格納しているサービスを示します。ほとんどの場合、ユーザーにはサービスに対する認証が求められます。
524たとえば、Google Contacts はアカウント タイプの 1 つで、コード <code>google.com</code> で識別されます。
525この値は、{@link android.accounts.AccountManager} によって使用されるアカウント タイプに対応します。
526
527    </dd>
528    <dt>
529        アカウント名
530    </dt>
531    <dd>
532        あるアカウント タイプで使用する特定のアカウントまたはログインを示します。Google Contacts アカウントは Google アカウントと同じで、アカウント名としてメールアドレスを使用します。
533
534        他のサービスでは、1 語のユーザー名や数字の ID が使われていることもあります。
535    </dd>
536</dl>
537<p>
538    アカウント タイプは、一意である必要はありません。1 人のユーザーが複数の Google Contacts アカウントを設定し、それぞれのデータを連絡先プロバイダにダウンロードする、ということが可能です。このような使い方は、そのユーザーが個人用のアカウント名で私用の連絡先を、仕事用のアカウント名で仕事用の連絡先を管理している場合にありえます。
539
540アカウント名は、普通は一意です。
541この 2 つを組み合わせて、連絡先プロバイダと外部サービスとの間のある決まったデータフローを識別します。
542
543</p>
544<p>
545    独自サービスのデータを連絡先プロバイダに転送する場合は、独自の同期アダプタを作成する必要があります。
546詳しくは、<a href="#SyncAdapters">連絡先プロバイダの同期アダプタ</a>をご覧ください。
547
548</p>
549<p>
550    図 4 に、人に関するデータの流れにおける連絡先プロバイダの位置付けを示します。
551右から 2 列目の各ボックス内のアダプタには、そのアダプタのアカウント タイプが示されています。
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>図 4.</strong> 連絡先プロバイダに絡んだデータフロー。
556</p>
557<h2 id="Permissions">必要なパーミッション</h2>
558<p>
559    連絡先プロバイダにアクセスするアプリケーションは、次のパーミッションを要求する必要があります。
560
561</p>
562<dl>
563    <dt>1 つ以上のテーブルに対する読み取りアクセス</dt>
564    <dd>
565        {@link android.Manifest.permission#READ_CONTACTS}。<code>AndroidManifest.xml</code> に <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">
566        &lt;uses-permission&gt;</a></code> 要素を使用して <code>&lt;uses-permission android:name="android.permission.READ_CONTACTS"&gt;</code> のように指定します。
567
568
569
570    </dd>
571    <dt>1 つ以上のテーブルに対する書き込みアクセス</dt>
572    <dd>
573        {@link android.Manifest.permission#WRITE_CONTACTS}。<code>AndroidManifest.xml</code> に <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">
574        &lt;uses-permission&gt;</a></code> 要素を使用して <code>&lt;uses-permission android:name="android.permission.WRITE_CONTACTS"&gt;</code> のように指定します。
575
576
577
578    </dd>
579</dl>
580<p>
581    これらのパーミッションは、ユーザー プロファイル データにまでは拡張されません。ユーザー プロファイルとそれに必要なパーミッションについては、次のセクションである<a href="#UserProfile">ユーザー プロファイル</a>で説明しています。
582
583
584</p>
585<p>
586    ユーザーの連絡先データは個人的で秘密性の高い情報であることを再度ご確認ください。ユーザーはプライバシーに敏感であり、アプリケーションが自分や自分の連絡先に関するデータを集めることを望みません。
587
588    連絡先データにアクセスするためのパーミッションが必要な理由が明らかでないと、ユーザーがアプリケーションを低く評価したりインストールを拒否したりすることがあります。
589
590</p>
591<h2 id="UserProfile">ユーザー プロファイル</h2>
592<p>
593    {@link android.provider.ContactsContract.Contacts} テーブルには、その端末のユーザーのプロファイル データを格納している行が 1 行あります。
594このデータが記述しているのは端末の <code>user</code> であって、そのユーザーの連絡先ではありません。
595プロファイルの連絡先の行は、プロファイルを使用する各システムの未加工連絡先の行にリンクされています。
596
597    プロファイルの未加工連絡先の各行は、複数のデータ行を持つことができます。ユーザー プロファイルにアクセスするための定数は、{@link android.provider.ContactsContract.Profile} クラスに用意されています。
598
599</p>
600<p>
601    ユーザー プロファイルにアクセスするには、特別なパーミッションが必要です。読み取りと書き込みに必要な {@link android.Manifest.permission#READ_CONTACTS} パーミッションと {@link android.Manifest.permission#WRITE_CONTACTS} パーミッションの他に、ユーザー プロファイルに対する読み取りと書き込みのために {@code android.Manifest.permission#READ_PROFILE} パーミッションと {@code android.Manifest.permission#WRITE_PROFILE} パーミッションがそれぞれ必要です。
602
603
604
605
606
607</p>
608<p>
609    ユーザーのプロファイルは秘密性の高い情報であることを再度ご確認ください。パーミッション {@code android.Manifest.permission#READ_PROFILE} を使用すると、端末ユーザーの個人識別データにアクセスできます。
610
611アプリケーションの説明には、ユーザー プロファイルへのアクセス パーミッションが必要な理由を必ず記載してください。
612
613</p>
614<p>
615    ユーザーのプロファイルが格納された連絡先の行を取得するには、{@link android.content.ContentResolver#query(Uri,String[], String, String[], String) ContentResolver.query()} を呼び出します。
616
617コンテンツ URI を {@link android.provider.ContactsContract.Profile#CONTENT_URI} に設定し、選択条件は何も指定しません。
618
619このコンテンツ URI は、そのプロファイルの未加工連絡先やデータを取得するためのベース URI としても使用できます。
620たとえば、次のスニペットは指定されたプロファイルのデータを取得します。
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>注:</strong> 連絡先の行を複数取得する場合、そのなかの 1 つがユーザー プロファイルかどうかを確認するには、行の {@link android.provider.ContactsContract.ContactsColumns#IS_USER_PROFILE} 列をテストします。
643
644その連絡先がユーザー プロファイルであれば、この列は「1」に設定されています。
645
646</p>
647<h2 id="ContactsProviderMetadata">連絡先プロバイダのメタデータ</h2>
648<p>
649    連絡先プロバイダは、連絡先データの状態を継続的に追跡するためのデータをリポジトリで管理します。
650リポジトリに関するこのメタデータは、RawContacts、Data、Contacts の各テーブルの行、{@link android.provider.ContactsContract.Settings} テーブル、{@link android.provider.ContactsContract.SyncState} テーブルなど、さまざまな場所に格納されています。
651
652
653次の表に、各メタデータの効果を示します。
654
655</p>
656<p class="table-caption" id="table3">
657  <strong>表 3.</strong> 連絡先プロバイダに用意されているメタデータ</p>
658<table>
659    <tr>
660        <th scope="col">テーブル</th>
661        <th scope="col">列</th>
662        <th scope="col">値</th>
663        <th scope="col">意味</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」 - 前回の同期以降、変更はありません。</td>
669        <td rowspan="2">
670            端末上で変更があり、サーバーと同期する必要がある未加工連絡先をマークします。
671Android アプリケーションが行をアップデートすると、連絡先プロバイダによって値が自動的に設定されます。
672
673            <p>
674                未加工連絡先やデータのテーブルを変更する同期アダプタは、使用するコンテンツ URI の末尾に文字列 {@link android.provider.ContactsContract#CALLER_IS_SYNCADAPTER} を必ず追加してください。
675
676これにより、プロバイダが行をダーティとマークするのを防ぐことができます。
677                こうしないと、同期アダプタによる変更がローカルな変更と認識され、変更のソースがサーバーであるにもかかわらず、その変更がサーバーに送信されます。
678
679            </p>
680        </td>
681    </tr>
682    <tr>
683            <td>「1」 - 前回の同期以降に変更があり、サーバーへの同期が必要です。</td>
684    </tr>
685    <tr>
686        <td>{@link android.provider.ContactsContract.RawContacts}</td>
687        <td>{@link android.provider.ContactsContract.SyncColumns#VERSION}</td>
688        <td>この行のバージョン番号。</td>
689        <td>
690            この行またはその関連データが変更されるたび、連絡先プロバイダがこの値を自動的にインクリメントします。
691
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>この行のバージョン番号。</td>
698        <td>
699            このデータ行が変更されるたび、連絡先プロバイダがこの値を自動的にインクリメントします。
700
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            この未加工連絡先をそれが作成されたアカウントと一意に結び付ける文字列値。
708
709        </td>
710        <td>
711            同期アダプタが新しい未加工連絡先を作成するたび、この列はその未加工連絡先に対するサーバーの一意の ID に設定される必要があります。
712Android アプリケーションが新しい未加工連絡先を作成した場合、そのアプリケーションはこの列を空欄のままにする必要があります。
713同期アダプタはこれを確認して、サーバー上に新しい未加工連絡先を作成し、{@link android.provider.ContactsContract.SyncColumns#SOURCE_ID} の値を取得します。
714
715
716            <p>
717                特に、ソース ID はアカウント タイプごとに<strong>一意</strong>で、同期中に安定している必要があります。
718
719            </p>
720                <ul>
721                    <li>
722                        Unique: アカウントの各未加工連絡先には独自のソース ID が必要です。これを強制しないと、連絡先アプリケーションに問題を引き起こすことになります。
723
724                        同じアカウント <em>タイプ</em>に対する 2 つの未加工連絡先が、同じソース ID を持つことがありえます。
725たとえば、アカウント {@code emily.dickinson@gmail.com} の未加工連絡先「Thomas Higginson」は、アカウント {@code emilyd@gmail.com} の未加工連絡先「Thomas Higginson」と同じソース ID を持つことができます。
726
727
728
729                    </li>
730                    <li>
731                        Stable: ソース ID は、未加工連絡先のオンライン サービス データにおいて変わらない部分です。
732たとえば、ユーザーが [アプリ] 設定から [連絡先ストレージ] を消去し、再同期したとしても、復元された未加工連絡先のソース ID は以前と同じになります。
733
734これを強制しないと、ショートカットが機能しなくなります。
735
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」 - このグループに属する連絡先が Android アプリケーションの UI に表示されなくなります。</td>
744        <td>
745            この列は、ユーザーが特定のグループに属する連絡先を非表示にすることを許可するサーバーに対して互換性を確保するために用意されています。
746
747        </td>
748    </tr>
749    <tr>
750        <td>「1」 - このグループに属する連絡先を Android アプリケーションの UI に表示できます。</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」 - このアカウントとアカウント タイプについて、グループに属さない連絡先は Android アプリケーションの UI に表示されなくなります。
758
759        </td>
760        <td rowspan="2">
761            デフォルトでは、グループに属する未加工連絡先がないなら連絡先は表示されません(未加工連絡先のグループ メンバーシップは、{@link android.provider.ContactsContract.Data} テーブルの 1 つないし複数の {@link android.provider.ContactsContract.CommonDataKinds.GroupMembership} 行によって示されます)。
762
763
764
765            あるアカウントとアカウント タイプについて、{@link android.provider.ContactsContract.Settings} テーブルの行でこのフラグを設定すると、グループのない連絡先を強制的に表示できます。
766
767            このフラグの用途の 1 つとして、グループを使用しないサーバーから連絡先を取得して表示することが考えられます。
768        </td>
769    </tr>
770    <tr>
771        <td>
772            「0」 - このアカウントとアカウント タイプについて、グループに属さない連絡先が Android アプリケーションの UI に表示されます。
773
774        </td>
775
776    </tr>
777    <tr>
778        <td>{@link android.provider.ContactsContract.SyncState}</td>
779        <td>(すべて)</td>
780        <td>
781            このテーブルを使用して、同期アダプタのメタデータを格納します。
782        </td>
783        <td>
784            このテーブルを使用すると、同期状態などの同期関連データを永続的に端末上に格納できます。
785
786        </td>
787    </tr>
788</table>
789<h2 id="Access">連絡先プロバイダへのアクセス</h2>
790<p>
791    このセクションでは、連絡先プロバイダからのデータにアクセスするためのガイドラインについて、以下に注目して説明します。
792
793</p>
794<ul>
795    <li>
796        エンティティ クエリ。
797    </li>
798    <li>
799        バッチ変更。
800    </li>
801    <li>
802        インテントを使用した取得と変更。
803    </li>
804    <li>
805        データ整合性。
806    </li>
807</ul>
808<p>
809    同期アダプタからの変更については、<a href="#SyncAdapters">連絡先プロバイダの同期アダプタ</a>でも詳しく説明しています。
810
811</p>
812<h3 id="Entities">エンティティのクエリ</h3>
813<p>
814    連絡先プロバイダのテーブルは階層構造になっており、ある行とその「子」の行すべてを取得すると便利なことがよくあります。
815たとえば、ある人に関するすべての情報を表示するために、{@link android.provider.ContactsContract.Contacts} 行 1 行に対するすべての {@link android.provider.ContactsContract.RawContacts} 行や、{@link android.provider.ContactsContract.RawContacts} 行 1 行に対するすべての {@link android.provider.ContactsContract.CommonDataKinds.Email} 行を取得することが考えられます。
816
817
818
819
820こうした処理をやりやすくするため、連絡先プロバイダには<strong>エンティティ</strong>構造が用意されています。これは、テーブル間でのデータベースの和集合のように機能します。
821
822
823</p>
824<p>
825    1 つのエンティティは、ある親テーブルとその子テーブルから選ばれた列からなるテーブルのようなものです。
826    エンティティをクエリする場合は、そのエンティティで使用できる列に基づいてプロジェクションと検索の条件を指定します。
827その結果が {@link android.database.Cursor} で、取得された各子テーブル行につき 1 行を含みます。
828たとえば、ある連絡先名と、その名前のすべての未加工連絡先の {@link android.provider.ContactsContract.CommonDataKinds.Email} 行について、{@link android.provider.ContactsContract.Contacts.Entity} をクエリすると、各 {@link android.provider.ContactsContract.CommonDataKinds.Email} 行につき 1 行を含む {@link android.database.Cursor} が得られます。
829
830
831
832
833</p>
834<p>
835    エンティティにより、クエリが簡素化されます。エンティティを使用することで、ある連絡先または未加工連絡先の連絡先データをすべて取得できるため、まず親テーブルにクエリして ID を取得し、次にその ID 使用して子テーブルにクエリする必要がありません。また、連絡先プロバイダは、エンティティに対するクエリを 1 回のトランザクションで処理することから、取得されたデータの内部的な整合性が保証されます。
836
837
838
839
840</p>
841<p class="note">
842    <strong>注:</strong> エンティティには通常、親テーブルと子テーブルのすべての列が含まれるわけではありません。
843そのエンティティの列名定数のリストにない列名に対して作業しようとすると、{@link java.lang.Exception} が発生します。
844
845</p>
846<p>
847    次のスニペットは、ある連絡先のすべての未加工連絡先を取得する方法を示しています。このスニペットは、「メイン」と「詳細」という 2 つのアクティビティを持つ、もっと大きなアプリケーションの一部です。
848メイン アクティビティは、連絡先の行の一覧を示します。ユーザーが 1 つを選択すると、このアクティビティはその ID を詳細アクティビティに送ります。
849
850詳細アクティビティは {@link android.provider.ContactsContract.Contacts.Entity} を使用して、選択した連絡先と関連付けられているすべての未加工連絡先から取得したすべてのデータ行を示します。
851
852
853</p>
854<p>
855    このスニペットは「詳細」アクティビティからの抜粋です。
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    読み込みが完了すると、{@link android.app.LoaderManager} は {@link android.app.LoaderManager.LoaderCallbacks#onLoadFinished(Loader, D) onLoadFinished()} に対するコールバックを起動します。
925
926このメソッドへの入力引数の 1 つは、クエリの結果を含む {@link android.database.Cursor} です。
927独自アプリでは、データをこの {@link android.database.Cursor} から取得して表示したりさらに処理したりできます。
928
929</p>
930<h3 id="Transactions">バッチ変更</h3>
931<p>
932    可能であれば必ず、連絡先プロバイダのデータを「バッチモード」で挿入、アップデート、削除してください。そのためには、{@link android.content.ContentProviderOperation} オブジェクトの {@link java.util.ArrayList} を作成し、{@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} を呼び出します。
933
934
935連絡先プロバイダはすべての操作を 1 つのトランザクションの 1 つの {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} で行うため、変更内容が連絡先リポジトリで不整合のままになることは決してありません。
936
937
938
939また、バッチ変更では、未加工連絡先とその詳細データを同時に挿入しやすくなっています。
940
941</p>
942<p class="note">
943    <strong>注:</strong> <em>1 つ</em>の未加工連絡先を変更する場合は、変更を独自アプリ内で処理するのではなく、インテントを端末の連絡先アプリケーションに送信することを検討してください。この方法については、<a href="#Intents">インテントを使用した取得と変更</a>で詳しく説明しています。
944
945
946
947</p>
948<h4>明け渡し点</h4>
949<p>
950    多数の操作を伴うバッチ変更は、他のプロセスをブロックしてユーザーにとっての全体的な使用感を悪化させかねません。
951意図したすべての変更をできるだけ少ない個別リストに整理するとともに、それらがシステムをブロックしないようにするために、1 つまたは複数の操作に<strong>明け渡し点</strong>を設定してください。
952
953
954    明け渡し点の実体は、{@link android.content.ContentProviderOperation#isYieldAllowed()} の値が <code>true</code> に設定された {@link android.content.ContentProviderOperation} オブジェクトです。
955
956連絡先プロバイダが明け渡し点に遭遇すると、作業を一時中断して他のプロセスを実行させ、現在のトランザクションをクローズします。
957作業を再開した連絡先プロバイダは、{@link java.util.ArrayList} に含まれている次の操作を行い、新しいトランザクションを始めます。
958
959
960</p>
961<p>
962    明け渡し点により、{@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} の呼び出し 1 回につき複数のトランザクションが発生します。
963そのため、明け渡し点は 1 組の関連する行への最後の操作に設定してください。
964
965    たとえば、未加工連絡先の行とその関連データ行を追加する一連の操作の最後に、あるいは 1 人の連絡先に関連する 1 組の行に対する最後の操作に、明け渡し点を設定します。
966
967
968</p>
969<p>
970    明け渡し点は、アトミック操作の単位でもあります。2 つの明け渡し点間のすべてのアクセスは、1 つのまとまりとして成功または失敗します。
971明け渡し点を設定しない場合、最小のアトミック操作は操作のバッチ全体になります。
972明け渡し点を使用すると、操作がシステムのパフォーマンスを低下させるのを防ぐと同時に、操作の一部分が確実にアトミックになります。
973
974
975</p>
976<h4>変更の後方参照</h4>
977<p>
978    新しい未加工連絡先の行とその関連データの行を 1 組の {@link android.content.ContentProviderOperation} オブジェクトとして挿入している場合は、データの行を未加工連絡先の行にリンクする必要があります。そのためには、未加工連絡先の {@code android.provider.BaseColumns#_ID} 値を {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID} 値として挿入します。
979
980
981
982ただし、この値は、データの行のために{@link android.content.ContentProviderOperation} を作成している間は使用できません。未加工連絡先に {@link android.content.ContentProviderOperation} 操作がまだ適用されていないからです。
983
984
985これを回避するため、{@link android.content.ContentProviderOperation.Builder} クラスにはメソッド {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()} が用意されています。
986
987
988    このメソッドを使用すると、前の操作の結果を使用して列を挿入または変更できます。
989
990</p>
991<p>
992    {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()} メソッドには引数が 2 つあります。
993
994</p>
995    <dl>
996        <dt>
997            <code>key</code>
998        </dt>
999        <dd>
1000            キーと値のペアのキーです。この引数の値は、変更中のテーブルに含まれる列であることが必要です。
1001
1002        </dd>
1003        <dt>
1004            <code>previousResult</code>
1005        </dt>
1006        <dd>
1007            {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} から取得した {@link android.content.ContentProviderResult} オブジェクトの配列に含まれる値の、0 ベースのインデックスです。
1008
1009バッチ操作が適用されると、各操作の結果は結果用の中間配列に格納されます。
1010
1011<code>previousResult</code> 値はそうした結果の 1 つのインデックスで、<code>key</code> 値を使用して取得され、格納されます。
1012
1013これにより、新しい未加工連絡先レコードを挿入してその {@code android.provider.BaseColumns#_ID} 値に戻り、次に {@link android.provider.ContactsContract.Data} 行を追加するときにその値を「後方参照」できます。
1014
1015
1016            <p>
1017                {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} を初めて呼び出すと、指定した {@link android.content.ContentProviderOperation} オブジェクトの {@link java.util.ArrayList} と同じサイズを使用して、結果配列全体が作成されます。
1018
1019
1020ただし、結果配列に含まれるすべての要素は <code>null</code> に設定され、そのためまだ適用されていない操作から結果を後方参照しようとすると {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()} が {@link java.lang.Exception} をスローします。
1021
1022
1023
1024
1025
1026            </p>
1027        </dd>
1028    </dl>
1029<p>
1030    次のスニペットは、新しい未加工連絡先とデータをバッチで挿入する方法を示しています。その中には、明け渡し点を指定し、後方参照を使用するコードが含まれています。
1031これらのスニペットは、<code><a href="{@docRoot}resources/samples/ContactManager/index.html">
1032    Contact Manager</a></code> サンプル アプリケーションの <code>ContactAdder</code> クラスの一部である <code>createContacEntry()</code> メソッドの拡張版です。
1033
1034
1035
1036</p>
1037<p>
1038    最初のスニペットは、連絡先データを UI から取得します。この時点で、ユーザーは新しい未加工連絡先の追加先となるアカウントを既に選択してあります。
1039
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    次のスニペットは、未加工連絡先の行を {@link android.provider.ContactsContract.RawContacts} テーブルに挿入する操作を作成します。
1059
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    次に、表示名、電話、メールのデータ行を作成します。
1087</p>
1088<p>
1089    操作の各ビルダー オブジェクトは、{@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()} を使用して {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID} を取得します。
1090
1091
1092この参照が最初の操作からの {@link android.content.ContentProviderResult} オブジェクトを後方参照しており、それが未加工連絡先の行を追加し、新しい {@code android.provider.BaseColumns#_ID} 値を返します。
1093
1094
1095その結果、各データ行はその {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID} によって、属する新しい {@link android.provider.ContactsContract.RawContacts} 行に自動的にリンクされます。
1096
1097
1098</p>
1099<p>
1100    メール行を追加する {@link android.content.ContentProviderOperation.Builder} オブジェクトは、明け渡し点を設定する {@link android.content.ContentProviderOperation.Builder#withYieldAllowed(boolean) withYieldAllowed()} でフラグ付けされます。
1101
1102
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    最後のスニペットは、新しい未加工連絡先とデータ行を挿入する {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} を呼び出しています。
1176
1177
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    バッチ処理を使用すると、<strong>楽観的並行性制御</strong>を実装できます。これは、背後のリポジトリをロックする必要なく変更トランザクションを適用する手法です。
1209
1210    この手法を使用するには、トランザクションを適用してから、同時に行うことのできる可能性のある他の変更をチェックします。
1211一貫性のない変更が発生していることがわかった場合は、トランザクションをロールバックしてやり直します。
1212
1213</p>
1214<p>
1215    楽観的並行性制御は、一度に使用するユーザーが 1 人でデータリポジトリへの同時アクセスがまれなモバイル端末に便利です。
1216ロックが使用されないため、ロックの設定や他のトランザクションによるロックの解放待ちで時間を無駄にしません。
1217
1218</p>
1219<p>
1220    {@link android.provider.ContactsContract.RawContacts} 行を 1 行更新している間に楽観的並行性制御を使用する方法は次のとおりです。
1221
1222</p>
1223<ol>
1224    <li>
1225        取得する他のデータとともに、未加工連絡先の {@link android.provider.ContactsContract.SyncColumns#VERSION} 列を取得します。
1226
1227    </li>
1228    <li>
1229        制約を強制するのに適した {@link android.content.ContentProviderOperation.Builder} オブジェクトを、メソッド {@link android.content.ContentProviderOperation#newAssertQuery(Uri)} を使用して作成します。
1230
1231コンテンツ URI に、未加工連絡先の {@code android.provider.BaseColumns#_ID} が末尾に追加された {@link android.provider.ContactsContract.RawContacts#CONTENT_URI RawContacts.CONTENT_URI} を使用します。
1232
1233
1234
1235    </li>
1236    <li>
1237        {@link android.content.ContentProviderOperation.Builder} オブジェクトに対し、{@link android.content.ContentProviderOperation.Builder#withValue(String, Object) withValue()} を呼び出して、{@link android.provider.ContactsContract.SyncColumns#VERSION} 列と取得したばかりのバージョン番号を比較します。
1238
1239
1240
1241    </li>
1242    <li>
1243        同じ {@link android.content.ContentProviderOperation.Builder} に対し、{@link android.content.ContentProviderOperation.Builder#withExpectedCount(int) withExpectedCount()} を呼び出して、このアサーションで 1 行だけがテストされるようにします。
1244
1245
1246    </li>
1247    <li>
1248        {@link android.content.ContentProviderOperation.Builder#build()} を呼び出して {@link android.content.ContentProviderOperation} オブジェクトを作成し、次のこのオブジェクトを {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} に渡す {@link java.util.ArrayList} に先頭オブジェクトとして追加します。
1249
1250
1251
1252    </li>
1253    <li>
1254        バッチトランザクションを適用します。
1255    </li>
1256</ol>
1257<p>
1258    目的の未加工連絡先の行が、行の読み込みからその変更の試行までの間に別の操作によってアップデートされた場合、{@link android.content.ContentProviderOperation} の「アサート」が失敗し、操作のバッチ全体がバックアウトされます。
1259
1260バックアウトが終わったら、バッチをやり直すこと、または他のアクションを行うことができます。
1261
1262</p>
1263<p>
1264    次のスニペットは、{@link android.content.CursorLoader} を使用して未加工連絡先を 1 つクエリした後に、{@link android.content.ContentProviderOperation} を「アサート」します。
1265
1266
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">インテントを使用した取得と変更</h3>
1313<p>
1314    インテントを端末の連絡先アプリケーションに送信すると、連絡先プロバイダに間接的にアクセスできます。
1315インテントが端末の連絡先アプリケーション UI を起動し、ユーザーはそこで連絡先関連の作業を行えます。
1316このタイプのアクセスで、ユーザーは次の作業ができます。
1317    <ul>
1318        <li>連絡先をリストから選び、アプリケーションに返してさらに作業する。</li>
1319        <li>既存の連絡先データを編集する。</li>
1320        <li>任意のアカウントに新しい未加工連絡先を挿入する。</li>
1321        <li>連絡先または連絡先データを削除する。</li>
1322    </ul>
1323<p>
1324    ユーザーがデータを挿入またはアップデートしている場合は、まずデータを収集し、次にそれをインテントの一部として送信できます。
1325
1326</p>
1327<p>
1328    インテントを使用して端末の連絡先アプリケーション経由で連絡先プロバイダにアクセスする場合、連絡先プロバイダにアクセスするための独自の UI やコードを作成する必要はありません。
1329また、連絡先プロバイダに対する読み取りや書き込みのパーミッションを要求する必要もありません。
1330端末の連絡先アプリケーションは、連絡先に対する読み取りパーミッションをデリゲートできます。また、連絡先プロバイダへの変更を他のアプリケーション経由で行っていることから、書き込みパーミッションは不要です。
1331
1332
1333</p>
1334<p>
1335    プロバイダにアクセスするためのインテントを送信する汎用プロセスについては、<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">コンテンツ プロバイダの基本</a>のセクション「インテント経由のデータアクセス」で詳しく説明しています。
1336
1337表 4 に、利用可能なタスクで使用できるアクション、MIME タイプ、データ値をまとめます。{@link android.content.Intent#putExtra(String, String) putExtra()} で使用できるエクストラ値については、{@link android.provider.ContactsContract.Intents.Insert} のリファレンス ドキュメントに一覧があります。
1338
1339
1340
1341
1342</p>
1343<p class="table-caption" id="table4">
1344  <strong>表 4.</strong> 連絡先プロバイダのインテント
1345</p>
1346<table style="width:75%">
1347    <tr>
1348        <th scope="col" style="width:10%">タスク</th>
1349        <th scope="col" style="width:5%">アクション</th>
1350        <th scope="col" style="width:10%">データ</th>
1351        <th scope="col" style="width:10%">MIME タイプ</th>
1352        <th scope="col" style="width:25%">注</th>
1353    </tr>
1354    <tr>
1355        <td><strong>連絡先をリストから選ぶ</strong></td>
1356        <td>{@link android.content.Intent#ACTION_PICK}</td>
1357        <td>
1358            次のどれかです。
1359            <ul>
1360                <li>
1361{@link android.provider.ContactsContract.Contacts#CONTENT_URI Contacts.CONTENT_URI}。連絡先のリストを表示します。
1362
1363                </li>
1364                <li>
1365{@link android.provider.ContactsContract.CommonDataKinds.Phone#CONTENT_URI Phone.CONTENT_URI}。未加工連絡先の電話番号のリストを表示します。
1366
1367                </li>
1368                <li>
1369{@link android.provider.ContactsContract.CommonDataKinds.StructuredPostal#CONTENT_URI StructuredPostal.CONTENT_URI}。未加工連絡先の住所のリストを表示します。
1370
1371
1372                </li>
1373                <li>
1374{@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_URI Email.CONTENT_URI}。未加工連絡先のメールアドレスのリストを表示します。
1375
1376                </li>
1377            </ul>
1378        </td>
1379        <td>
1380            使用せず
1381        </td>
1382        <td>
1383            指定したコンテンツ URI のタイプに応じて、未加工連絡先のリストか、未加工連絡先から取得されたデータのリストを表示します。
1384
1385            <p>
1386                {@link android.app.Activity#startActivityForResult(Intent, int) startActivityForResult()} を呼び出してください。それにより、選択した行のコンテンツ URI が返されます。
1387
1388URI の形式は、テーブルのコンテンツ URI の末尾にその行の <code>LOOKUP_ID</code> が追加されたものです。
1389
1390                端末の連絡先アプリは、このアクティビティの実行中を通して、読み取りと書き込みのパーミッションをこのコンテンツ URI にデリゲートします。
1391詳しくは、「<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">コンテンツ プロバイダの基本</a>」をご覧ください。
1392
1393
1394            </p>
1395        </td>
1396    </tr>
1397    <tr>
1398        <td><strong>新しい未加工連絡先を挿入する</strong></td>
1399        <td>{@link android.provider.ContactsContract.Intents.Insert#ACTION Insert.ACTION}</td>
1400        <td>該当せず</td>
1401        <td>
1402            {@link android.provider.ContactsContract.RawContacts#CONTENT_TYPE RawContacts.CONTENT_TYPE}。未加工連絡先のセットに対する MIME タイプです。
1403
1404        </td>
1405        <td>
1406            端末の連絡先アプリケーションの [<strong>連絡先の追加</strong>] 画面を表示します。インテントに追加したエクストラ値が表示されます。
1407{@link android.app.Activity#startActivityForResult(Intent, int) startActivityForResult()} を使用して送信すると、新たに追加された未加工連絡先の URI が、アクティビティの {@link android.app.Activity#onActivityResult(int, int, Intent) onActivityResult()} コールバック メソッドの {@link android.content.Intent} 引数の「data」フィールドに格納されて戻ってきます。
1408
1409
1410
1411
1412この値を取得するには、{@link android.content.Intent#getData()} を呼び出します。
1413        </td>
1414    </tr>
1415    <tr>
1416        <td><strong>連絡先を編集する</strong></td>
1417        <td>{@link android.content.Intent#ACTION_EDIT}</td>
1418        <td>
1419            連絡先の {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}。
1420エディタ アクティビティを使用すると、ユーザーがその連絡先に関連付けられている任意のデータを編集できます。
1421
1422        </td>
1423        <td>
1424            {@link android.provider.ContactsContract.Contacts#CONTENT_ITEM_TYPE Contacts.CONTENT_ITEM_TYPE}。1 つの連絡先です。
1425</td>
1426        <td>
1427            連絡先アプリケーションに連絡先の編集画面を表示します。インテントに追加したエクストラ値が表示されます。
1428ユーザーが [<strong>完了</strong>] をタップして編集内容を保存すると、アクティビティがフォアグラウンドに戻ります。
1429
1430        </td>
1431    </tr>
1432    <tr>
1433        <td><strong>ピッカー(やはりデータを追加できる)を表示する。</strong></td>
1434        <td>{@link android.content.Intent#ACTION_INSERT_OR_EDIT}</td>
1435        <td>
1436            該当せず
1437        </td>
1438        <td>
1439            {@link android.provider.ContactsContract.Contacts#CONTENT_ITEM_TYPE}
1440        </td>
1441         <td>
1442            このインテントは、連絡先アプリのピッカー画面を常に表示します。ユーザーは、編集する連絡先を選ぶか、新しい連絡先を追加できます。
1443ユーザーの選択に応じて編集画面か追加画面が開き、インテントに含めて渡したエクストラ データが表示されます。
1444
1445メールアドレスや電話番号などの連絡先データを独自アプリに表示する場合は、このインテントを使用すると、ユーザーが既存の連絡先にデータを追加できます。
1446
1447
1448            <p class="note">
1449                <strong>注:</strong> このインテントのエクストラで名前の値を送信する必要はありません。ユーザーは必ず既存の名前を選ぶか新しい名前を追加するからです。
1450そのうえ、アプリが名前を送信し、ユーザーが編集することを選んだ場合、連絡先アプリは送信した名前を表示し、以前の値を上書きします。
1451
1452ユーザーがこのことに気付かず、編集内容を保存すると、以前の値が失われます。
1453
1454            </p>
1455         </td>
1456    </tr>
1457</table>
1458<p>
1459    端末の連絡先アプリは、インテントを使用して未加工連絡先や任意のデータを削除することを許可しません。
1460そのため、未加工連絡先を削除するには {@link android.content.ContentResolver#delete(Uri, String, String[]) ContentResolver.delete()} または {@link android.content.ContentProviderOperation#newDelete(Uri) ContentProviderOperation.newDelete()} を使用してください。
1461
1462
1463
1464</p>
1465<p>
1466    次のスニペットは、新しい未加工連絡先とデータをバッチで挿入するインテントをコンストラクトして送信する方法を示しています。
1467
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">データの整合性</h3>
1562<p>
1563    連絡先リポジトリにはユーザーによる修正や更新が予想される重要で秘密性の高いデータが格納されるため、連絡先プロバイダにはデータの整合性に関して明確に定義されたルールがあります。
1564連絡先データを変更する際にこれらのルールを守ることは、開発側の責任です。
1565ここでは、重要なルールを示します。
1566
1567</p>
1568<dl>
1569    <dt>
1570        {@link android.provider.ContactsContract.CommonDataKinds.StructuredName} 行を、追加する {@link android.provider.ContactsContract.RawContacts} 行ごとに必ず追加してください。
1571
1572    </dt>
1573    <dd>
1574        {@link android.provider.ContactsContract.Data} テーブルに {@link android.provider.ContactsContract.CommonDataKinds.StructuredName} 行のない {@link android.provider.ContactsContract.RawContacts} 行は、集約中に問題を引き起こすことがあります。
1575
1576
1577
1578    </dd>
1579    <dt>
1580        新しい {@link android.provider.ContactsContract.Data} 行を、その親 {@link android.provider.ContactsContract.RawContacts} 行に必ずリンクしてください。
1581
1582    </dt>
1583    <dd>
1584        {@link android.provider.ContactsContract.RawContacts} にリンクされていない {@link android.provider.ContactsContract.Data} 行は端末の連絡先アプリケーションで可視にならず、同期アダプタで問題になることがあります。
1585
1586
1587    </dd>
1588    <dt>
1589        変更するのは、所有する未加工連絡先のデータに限ってください。
1590    </dt>
1591    <dd>
1592        通常、連絡先プロバイダは複数の異なるアカウント タイプやオンライン サービスから取得したデータを管理しています。
1593そのため、アプリケーションが所有しているデータのみ変更または削除されるようにし、アプリケーションが管理しているアカウント タイプとアカウント名のデータのみ挿入するようにすることが必要です。
1594
1595
1596    </dd>
1597    <dt>
1598        権限、コンテンツ URI、URI パス、列名、MIME タイプ、{@link android.provider.ContactsContract.CommonDataKinds.CommonColumns#TYPE} 値については、{@link android.provider.ContactsContract} とそのサブクラスに定義されている定数を必ず使用してください。
1599
1600
1601    </dt>
1602    <dd>
1603        そのような定数を使用することがエラーの予防に役立ちます。また、使われなくなった定数があれば、コンパイラーから警告として通知されます。
1604
1605    </dd>
1606</dl>
1607<h3 id="CustomData">カスタムデータ行</h3>
1608<p>
1609    独自のカスタム MIME タイプを作成して使用すると、{@link android.provider.ContactsContract.Data} テーブルで独自データ行を挿入、編集、削除、取得できます。
1610独自行で使用できるのは {@link android.provider.ContactsContract.DataColumns} に定義された列だけですが、独自タイプに固有の列名をデフォルトの列名にマッピングできます。
1611
1612
1613端末の連絡先アプリケーションで、独自行のデータは表示されますが、編集または削除はできず、ユーザーはデータの追加ができません。
1614
1615ユーザーがカスタムデータ行を変更できるようにするには、独自のアプリケーションでエディタ アクティビティを提供する必要があります。
1616
1617</p>
1618<p>
1619    カスタムデータを表示するには、1 つの <code>&lt;ContactsAccountType&gt;</code> 要素と 1 つまたは複数の <code>&lt;ContactsDataKind&gt;</code> 子要素を含む <code>contacts.xml</code> ファイルを提供します。
1620
1621詳しくは、<a href="#SocialStreamDataKind"><code>&lt;ContactsDataKind&gt; element</code></a>に関するセクションで説明しています。
1622
1623</p>
1624<p>
1625    カスタム MIME タイプについて詳しくは、「<a href="{@docRoot}guide/topics/providers/content-provider-creating.html">コンテンツ プロバイダの作成</a>」をご覧ください。
1626
1627
1628</p>
1629<h2 id="SyncAdapters">連絡先プロバイダの同期アダプタ</h2>
1630<p>
1631    連絡先プロバイダは、特に端末とオンライン サービスとの間における連絡先データの<strong>同期</strong>を処理するために設計されています。
1632これを使用することで、ユーザーは既存のデータを新しい端末にダウンロードしたり、既存のデータを新しいアカウントにアップロードしたりできています。
1633
1634    また、同期によって、追加や変更のソースに関係なく、ユーザーは最新データを入手できます。
1635同期の利点としては他にも、端末がネットワークに接続されていなくても連絡先データを使用できるようになることが挙げられます。
1636
1637</p>
1638<p>
1639    同期はさまざまな手法で実装できますが、Android システムでは次のタスクを自動化するプラグイン同期フレームワークを提供しています。
1640
1641    <ul>
1642
1643    <li>
1644        ネットワークの可用性のチェック。
1645    </li>
1646    <li>
1647        ユーザーのプリファレンスに基づく同期のスケジュールと実施。
1648    </li>
1649    <li>
1650        停止された同期の再開。
1651    </li>
1652    </ul>
1653<p>
1654    このフレームワークを使用するには、同期アダプタ プラグインを提供する必要があります。各同期アダプタはサービスと連絡先プロバイダに対して一意ですが、同じサービスに対して複数のアカウント名を処理できます。
1655また、このフレームワークでは同じサービスとプロバイダに対して複数の同期アダプタが可能です。
1656
1657</p>
1658<h3 id="SyncClassesFiles">同期アダプタのクラスとファイル</h3>
1659<p>
1660    同期アダプタは、{@link android.content.AbstractThreadedSyncAdapter} のサブクラスとして実装し、Android アプリケーションの一部としてインストールします。
1661
1662システムは同期アダプタに関する知識を、アプリケーション マニフェストの要素からと、マニフェストが指す専用の XML ファイルから取得します。
1663この XML ファイルは、オンライン サービスのアカウント タイプと連絡先プロバイダに絡む権限を定義しており、この組み合わせでアダプタを一意に識別します。
1664
1665同期アダプタは、ユーザーが同期アダプタのアカウント タイプに対してアカウントを追加し、同期アダプタの同期対象である連絡先プロバイダで同期を有効にすることで、アクティブになります。
1666
1667この時点で、システムはアダプタの管理を開始し、連絡先プロバイダとサーバーとの同期が必要になるとそれを呼び出します。
1668
1669</p>
1670<p class="note">
1671    <strong>注:</strong> アカウント タイプを同期アダプタの識別の一環として使用することにより、システムは同じ組織から異なるサービスにアクセスする同期アダプタを検出してグループ化できます。
1672
1673たとえば、Google オンライン サービス用の同期アダプタでは、すべて同じアカウント タイプ <code>com.google</code> です。
1674ユーザーが Google アカウントを端末に追加すると、Google サービス用にインストールされているすべての同期アダプタがひとまとめにリストされ、リストされている各同期アダプタは端末上の異なる連絡先プロバイダと同期します。
1675
1676
1677</p>
1678<p>
1679    データにアクセスするたび、ほとんどのサービスがユーザーに ID の確認を要求するため、Android システムでは、同期アダプタ フレームワークと類似した認証フレームワークを提供しており、往々にして同期アダプタ フレームワークと組み合わせて使用します。
1680
1681この認証フレームワークでは、{@link android.accounts.AbstractAccountAuthenticator} のサブクラスであるプラグイン認証システムを使用します。
1682
1683認証システムは、次の手順でユーザーの身元を検証します。
1684
1685    <ol>
1686        <li>
1687            ユーザー名とパスワードか、それに準ずる情報(ユーザーの<strong>資格情報</strong>)を収集します。
1688
1689        </li>
1690        <li>
1691            収集した資格情報をサービスに送信します。
1692        </li>
1693        <li>
1694            サービスの返答を検証します。
1695        </li>
1696    </ol>
1697<p>
1698    サービスが資格情報を受け入れた場合、認証システムはその資格情報を後での使用のために格納します。
1699{@link android.accounts.AccountManager} はプラグイン認証フレームワークのおかげで、OAuth2 認証トークンなど、認証システムがサポートして公開することを選択している任意の認証トークンへのアクセスを提供できます。
1700
1701
1702</p>
1703<p>
1704    認証は必須ではありませんが、たいていの連絡先サービスが使用しています。
1705    ただし、認証に Android 認証フレームワークを使用する必要はありません。
1706</p>
1707<h3 id="SyncAdapterImplementing">同期アダプタの実装</h3>
1708<p>
1709    連絡先プロバイダ用の同期アダプタを実装するには、まず以下を備えた Android アプリケーションを作成します。
1710
1711</p>
1712    <dl>
1713        <dt>
1714            システムからの同期アダプタとのバインド要求に対処する {@link android.app.Service} コンポーネント。
1715
1716        </dt>
1717        <dd>
1718            システムは、同期しようとするとき、サービスの {@link android.app.Service#onBind(Intent) onBind()} メソッドを呼び出して、同期アダプタの {@link android.os.IBinder} を取得します。
1719
1720これにより、システムはアダプタのメソッドに対するプロセス間呼び出しを実行できます。
1721
1722            <p>
1723                <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">サンプル同期アダプタ</a>のサンプルアプリで、このサービスのクラス名は <code>com.example.android.samplesync.syncadapter.SyncService</code> です。
1724
1725
1726            </p>
1727        </dd>
1728        <dt>
1729            {@link android.content.AbstractThreadedSyncAdapter} の具象サブクラスとして実装された、実際の同期アダプタ。
1730
1731        </dt>
1732        <dd>
1733            このクラスが、サーバーからのデータのダウンロード、端末からのデータのアップロード、競合の解消といった作業を実施します。
1734アダフタの主な作業は、メソッド {@link android.content.AbstractThreadedSyncAdapter#onPerformSync( Account, Bundle, String, ContentProviderClient, SyncResult) onPerformSync()} で実行されます。
1735
1736
1737このクラスは、シングルトンとしてインスタンス化する必要があります。
1738            <p>
1739                <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">サンプル同期アダプタ</a>のサンプルアプリで、同期アダプタはクラス <code>com.example.android.samplesync.syncadapter.SyncAdapter</code> に定義されています。
1740
1741
1742            </p>
1743        </dd>
1744        <dt>
1745            {@link android.app.Application} のサブクラス。
1746        </dt>
1747        <dd>
1748            このクラスは同期アダプタ シングルトンのファクトリとして機能します。同期アダプタのインスタンス化には {@link android.app.Application#onCreate()} メソッドを使用し、同期アダプタ シングルトンを同期アダプタのサービスの {@link android.app.Service#onBind(Intent) onBind()} メソッドに返すための静的な「getter」メソッドを提供します。
1749
1750
1751
1752
1753        </dd>
1754        <dt>
1755            <strong>省略可能:</strong> システムからのユーザー認証要求に対処する {@link android.app.Service} コンポーネント。
1756
1757        </dt>
1758        <dd>
1759            {@link android.accounts.AccountManager} は、このサービスを開始することによって認証プロセスを始めます。
1760サービスの {@link android.app.Service#onCreate()} メソッドは、認証システム オブジェクトをインスタンス化します。
1761システムは、アプリケーションの同期アダプタのためにユーザー アカウントを認証しようとするとき、サービスの {@link android.app.Service#onBind(Intent) onBind()} メソッドを呼び出して、認証システムの {@link android.os.IBinder} を取得します。
1762
1763
1764これにより、システムは認証システムのメソッドに対するプロセス間呼び出しを実行できます。
1765
1766            <p>
1767                <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">サンプル同期アダプタ</a>のサンプルアプリで、このサービスのクラス名は <code>com.example.android.samplesync.authenticator.AuthenticationService</code> です。
1768
1769
1770            </p>
1771        </dd>
1772        <dt>
1773            <strong>省略可能:</strong> 認証の要求を処理する {@link android.accounts.AbstractAccountAuthenticator} の具象サブクラス。
1774
1775
1776        </dt>
1777        <dd>
1778            このクラスは、ユーザーの資格情報をサーバーに対して認証するために {@link android.accounts.AccountManager} が呼び出すメソッドを提供します。認証プロセスの詳細は、使用されているサーバー技術に応じて多岐にわたります。
1779
1780認証について詳しくは、使用するサーバー ソフトウェアのドキュメントをご覧ください。
1781
1782            <p>
1783                <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">サンプル同期アダプタ</a>のサンプルアプリで、認証はクラス <code>com.example.android.samplesync.authenticator.Authenticator</code> に定義されています。
1784
1785
1786            </p>
1787        </dd>
1788        <dt>
1789            システムに対する同期アダプタと認証システムを定義する XML ファイル。
1790        </dt>
1791        <dd>
1792            前述の同期アダプタと認証システム サービスのコンポーネントは、アプリケーション マニフェストの <code>&lt;<a href="{@docRoot}guide/topics/manifest/service-element.html">service</a>&gt;</code> 要素に定義されます。
1793
1794
1795これらの要素には、特定のデータをシステムに提供する次のような <code>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</code> 子要素が含まれます。
1796
1797
1798
1799
1800            <ul>
1801                <li>
1802                    同期アダプタ サービス用の <code>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</code> 要素は、XML ファイル <code>res/xml/syncadapter.xml</code> を指します。
1803
1804
1805このファイルが、連絡先プロバイダと同期されるウェブサービスの URI と、そのウェブサービスで使用するアカウント タイプを指定します。
1806
1807
1808                </li>
1809                <li>
1810                    <strong>省略可能:</strong> 認証システム用の <code>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</code> 要素は、XML ファイル <code>res/xml/authenticator.xml</code> を指します。
1811
1812
1813このファイルが、この認証システムがサポートするアカウント タイプと、認証プロセスの最中に表示される UI リソースを指定します。
1814
1815この要素に指定されるアカウント タイプは、同期アダプタ用に指定されるアカウント タイプと同じであることが必要です。
1816
1817
1818                </li>
1819            </ul>
1820        </dd>
1821    </dl>
1822<h2 id="SocialStream">ソーシャル ストリーム データ</h2>
1823<p>
1824    {@code android.provider.ContactsContract.StreamItems} テーブルと {@code android.provider.ContactsContract.StreamItemPhotos} テーブルは、ソーシャル ネットワークからの受信データを管理します。
1825
1826独自ネットワークからのストリーム データをこれらのテーブルに追加する同期アダプタを作成したり、ストリーム データをこれらのテーブルから読み込んで独自アプリケーションに表示したり、この両方を行ったりできます。
1827
1828このような機能があると、ソーシャル ネットワーキングのサービスやアプリケーションを Android のソーシャル ネットワーキング機能に統合できます。
1829
1830</p>
1831<h3 id="StreamText">ソーシャル ストリーム テキスト</h3>
1832<p>
1833    ストリーム アイテムは、必ず未加工連絡先に関連付けられます。{@code android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID} は、未加工連絡先の <code>_ID</code> 値にリンクされます。
1834
1835未加工連絡先のアカウント タイプとアカウント名は、ストリーム アイテム行にも格納されます。
1836
1837</p>
1838<p>
1839    ストリームからのデータを次の列に格納します。
1840</p>
1841<dl>
1842    <dt>
1843        {@code android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_TYPE}
1844    </dt>
1845    <dd>
1846        <strong>必須</strong>。このストリーム アイテムに関連付けられている未加工連絡先の、ユーザーのアカウント タイプ。
1847ストリーム アイテムを挿入する際には、この値を忘れずに設定してください。
1848    </dd>
1849    <dt>
1850        {@code android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_NAME}
1851    </dt>
1852    <dd>
1853        <strong>必須</strong>。このストリーム アイテムに関連付けられている未加工連絡先の、ユーザーのアカウント名。
1854ストリーム アイテムを挿入する際には、この値を忘れずに設定してください。
1855    </dd>
1856    <dt>
1857        識別用列
1858    </dt>
1859    <dd>
1860        <strong>必須</strong>。ストリーム アイテムを挿入する際には、次の識別用列を挿入する必要があります。
1861
1862        <ul>
1863            <li>
1864                {@code android.provider.ContactsContract.StreamItemsColumns#CONTACT_ID}:このストリーム アイテムが関連付けられている連絡先の {@code android.provider.BaseColumns#_ID} 値。
1865
1866
1867            </li>
1868            <li>
1869                {@code android.provider.ContactsContract.StreamItemsColumns#CONTACT_LOOKUP_KEY}: このストリーム アイテムが関連付けられている連絡先の {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} 値。
1870
1871
1872            </li>
1873            <li>
1874                {@code android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID}:このストリーム アイテムが関連付けられている未加工連絡先の {@code android.provider.BaseColumns#_ID} 値。
1875
1876
1877            </li>
1878        </ul>
1879    </dd>
1880    <dt>
1881        {@code android.provider.ContactsContract.StreamItemsColumns#COMMENTS}
1882    </dt>
1883    <dd>
1884        省略可能。ストリーム アイテムの冒頭に表示できる概要情報を格納します。
1885    </dd>
1886    <dt>
1887        {@code android.provider.ContactsContract.StreamItemsColumns#TEXT}
1888    </dt>
1889    <dd>
1890        ストリーム アイテムのテキスト。アイテムのソースによって投稿されたコンテンツか、そのストリーム アイテムを生成した何らかのアクションに関する説明です。
1891この列には、{@link android.text.Html#fromHtml(String) fromHtml()} でレンダリングできる任意の書式や埋め込みリソース画像を含めることができます。
1892
1893プロバイダは、長いコンテンツを切り捨てたり省いたりすることがありますが、タグは壊さないようにします。
1894
1895    </dd>
1896    <dt>
1897        {@code android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP}
1898    </dt>
1899    <dd>
1900        ストリーム アイテムが挿入またはアップデートされた時刻を含むテキスト。エポックからのミリ秒<em></em>の形式です。
1901ストリーム アイテムを挿入またはアップデートするアプリケーションは、この列の管理を担当します。この列は、連絡先プロバイダによって自動的に管理されるわけではありません。
1902
1903
1904    </dd>
1905</dl>
1906<p>
1907    ストリーム アイテムの識別情報を表示するには、{@code android.provider.ContactsContract.StreamItemsColumns#RES_ICON}、{@code android.provider.ContactsContract.StreamItemsColumns#RES_LABEL}、{@code android.provider.ContactsContract.StreamItemsColumns#RES_PACKAGE} を使用してアプリケーション内のリソースにリンクします。
1908
1909
1910
1911
1912</p>
1913<p>
1914    {@code android.provider.ContactsContract.StreamItems} テーブルには、同期アダプタ専用に列 {@code android.provider.ContactsContract.StreamItemsColumns#SYNC1} ~ {@code android.provider.ContactsContract.StreamItemsColumns#SYNC4} も格納されます。
1915
1916
1917
1918</p>
1919<h3 id="StreamPhotos">ソーシャル ストリーム フォト</h3>
1920<p>
1921   {@code android.provider.ContactsContract.StreamItemPhotos} テーブルには、ストリーム アイテムに関連付けられた写真が格納されます。
1922このテーブルの {@code android.provider.ContactsContract.StreamItemPhotosColumns#STREAM_ITEM_ID} 列は、{@code android.provider.ContactsContract.StreamItems} テーブルの {@code android.provider.BaseColumns#_ID} 列の値にリンクされます。
1923
1924
1925写真の参照は、テーブルの次の列に格納されます。
1926
1927</p>
1928<dl>
1929    <dt>
1930        {@code android.provider.ContactsContract.StreamItemPhotos#PHOTO} 列(BLOB)。
1931    </dt>
1932    <dd>
1933        写真のバイナリ表現。格納や表示のためにプロバイダによってサイズが変更されます。
1934        この列は、写真を格納するために使用されていた連絡先プロバイダの従来のバージョンとの下方互換性のために用意されています。
1935ただし、現在のバージョンでは、写真の格納にこの列を使用しないでください。
1936代わりに、{@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID} または {@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI}(どちらについても次の項目で説明します)を使用して、写真をファイルに保存します。
1937
1938
1939現状では、この列には写真のサムネイルが格納されており、読み出し可能です。
1940
1941    </dd>
1942    <dt>
1943        {@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID}
1944    </dt>
1945    <dd>
1946        未加工連絡先の写真の数値 ID。この値を定数 {@link android.provider.ContactsContract.DisplayPhoto#CONTENT_URI DisplayPhoto.CONTENT_URI} の末尾に追加して、1 つの写真ファイルを指すコンテンツ URI を取得し、{@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String) openAssetFileDescriptor()} を呼び出して、その写真ファイルのハンドルを取得します。
1947
1948
1949
1950
1951    </dd>
1952    <dt>
1953        {@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI}
1954    </dt>
1955    <dd>
1956        この行によって表されている写真の写真ファイルを直接指すコンテンツ URI。
1957        この URI を使用して {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String) openAssetFileDescriptor()} を呼び出して、写真ファイルのハンドルを取得します。
1958
1959    </dd>
1960</dl>
1961<h3 id="SocialStreamTables">ソーシャル ストリーム テーブルの使用</h3>
1962<p>
1963    これらのテーブルは、連絡先プロバイダの他の主なテーブルと同じように機能しますが、次のような例外があります。
1964</p>
1965    <ul>
1966        <li>
1967            これらのテーブルには、追加のアクセス パーミッションが必要です。これらからの読み出しには、アプリケーションにパーミッション {@code android.Manifest.permission#READ_SOCIAL_STREAM} が必要です。
1968これらの変更には、アプリケーションにパーミッション {@code android.Manifest.permission#WRITE_SOCIAL_STREAM} が必要です。
1969
1970
1971        </li>
1972        <li>
1973            {@code android.provider.ContactsContract.StreamItems} テーブルについては、各未加工連絡先に格納できる行数に上限があります。
1974上限に達すると、連絡先プロバイダは最も古い {@code android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP} を持つ行を自動的に削除して、新しいストリーム アイテムのための領域を作ります。
1975
1976
1977この上限を取得するには、コンテンツ URI {@code android.provider.ContactsContract.StreamItems#CONTENT_LIMIT_URI} にクエリを発行します。
1978
1979コンテンツ URI を除くすべての引数は、<code>null</code> のままでかまいません。
1980このクエリは、列 {@code android.provider.ContactsContract.StreamItems#MAX_ITEMS} だけの 1 行を含む Cursor を返します。
1981
1982
1983        </li>
1984    </ul>
1985
1986<p>
1987    クラス {@code android.provider.ContactsContract.StreamItems.StreamItemPhotos} は、1 つのストリーム アイテムの写真行を含む {@code android.provider.ContactsContract.StreamItemPhotos} のサブテーブルを定義します。
1988
1989
1990</p>
1991<h3 id="SocialStreamInteraction">ソーシャル ストリーム操作</h3>
1992<p>
1993    連絡先プロバイダによって端末の連絡先アプリケーションと連携して管理されるソーシャル ストリーム データは、ソーシャル ネットワーキング システムと既存の連絡先を接続するためのとても便利な手段を用意しています。
1994
1995利用できる機能は次のとおりです。
1996</p>
1997    <ul>
1998        <li>
1999            ソーシャル ネットワーキング サービスを連絡先プロバイダに同期アダプタを使用して同期することで、ユーザーの連絡先による最近のアクティビティを取得し、それを {@code android.provider.ContactsContract.StreamItems} テーブルや {@code android.provider.ContactsContract.StreamItemPhotos} テーブルに格納して後で使えるようにできます。
2000
2001
2002
2003        </li>
2004        <li>
2005            ユーザーが連絡先を選択して表示したときには、定期的な同期とは別に同期アダプタを起動して追加データを取得できます。
2006この機能により、同期アダプタは連絡先の高解像度の写真や直近のストリーム アイテムを取得できます。
2007
2008        </li>
2009        <li>
2010            端末の連絡先アプリケーションと連絡先プロバイダに関する通知を登録すると、連絡先が表示された場合にインテントを受信<em></em>し、その時点で連絡先のステータスをサービスからアップデートできます。
2011
2012このアプローチは、同期アダプタを使用してフル同期を実施するより、処理が速く、帯域幅が節約されます。
2013
2014        </li>
2015        <li>
2016            ユーザーが端末の連絡先アプリケーションで連絡先を見ている間に、その連絡先をソーシャル ネットワーキング サービスに追加できます。
2017この機能は「連絡先の招待」機能を使用して実現できます。連絡先の招待は、既存の連絡先をネットワークに追加するアクティビティと、端末の連絡先アプリケーションと連絡先プロバイダにアプリケーションの詳細を提供する XML ファイルとを組み合わせて実現できます。
2018
2019
2020
2021        </li>
2022    </ul>
2023<p>
2024    連絡先プロバイダを使用したストリーム アイテムの定期的な同期は、他の同期と同じです。
2025同期について詳しくは、<a href="#SyncAdapters">連絡先プロバイダの同期アダプタ</a>をご覧ください。
2026通知の登録と連絡先の招待については、次の 2 つのセクションで説明します。
2027
2028</p>
2029<h4>ソーシャル ネットワーキング表示を処理するための登録</h4>
2030<p>
2031    同期アダプタを登録し、同期アダプタによって管理されている連絡先をユーザーが表示したときに通知されるようにする方法は、次のとおりです。
2032
2033</p>
2034<ol>
2035    <li>
2036        <code>contacts.xml</code> という名前のファイルをプロジェクトの <code>res/xml/</code> ディレクトリに作成します。
2037このファイルが既に存在する場合は、この手順を省略できます。
2038    </li>
2039    <li>
2040        このファイルに要素 <code>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</code> を追加します。
2041
2042        この要素が既に存在する場合は、この手順を省略できます。
2043    </li>
2044    <li>
2045        ユーザーが端末の連絡先アプリケーションで連絡先の詳細ページを開いたときに通知されるサービスを登録するには、属性 <code>viewContactNotifyService="<em>serviceclass</em>"</code> を要素に追加します。<code><em>serviceclass</em></code> は、端末の連絡先アプリケーションからインテントを受け取ることになるサービスの完全修飾クラス名です。
2046
2047
2048
2049通知側サービスのために、{@link android.app.IntentService} を機能拡張したクラスを使用して、そのサービスがインテントを受け取れるようにします。
2050
2051受け取るインテントに含まれるデータには、ユーザーがクリックした未加工連絡先のコンテンツ URI が格納されます。
2052通知側サービスから、同期アダプタをバインドして呼び出し、未加工連絡先のデータをアップデートできます。
2053
2054    </li>
2055</ol>
2056<p>
2057    ユーザーがストリーム アイテムかストリーム フォトかその両方をクリックしたときに呼び出されるアクティビティを登録する方法は次のとおりです。
2058</p>
2059<ol>
2060    <li>
2061        <code>contacts.xml</code> という名前のファイルをプロジェクトの <code>res/xml/</code> ディレクトリに作成します。
2062このファイルが既に存在する場合は、この手順を省略できます。
2063    </li>
2064    <li>
2065        このファイルに要素 <code>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</code> を追加します。
2066
2067        この要素が既に存在する場合は、この手順を省略できます。
2068    </li>
2069    <li>
2070        アクティビティのどれかを登録して、ユーザーが端末の連絡先アプリケーションでストリーム アイテムをタップしたことに対処するには、属性 <code>viewStreamItemActivity="<em>activityclass</em>"</code> を要素に追加します。<code><em>activityclass</em></code> は、端末の連絡先アプリケーションからインテントを受け取ることになるアクティビティの完全修飾クラス名です。
2071
2072
2073
2074
2075    </li>
2076    <li>
2077        アクティビティのどれかを登録して、ユーザーが端末の連絡先アプリケーションでストリーム フォトをタップしたことに対処するには、属性 <code>viewStreamItemPhotoActivity="<em>activityclass</em>"</code> を要素に追加します。<code><em>activityclass</em></code> は、端末の連絡先アプリケーションからインテントを受け取ることになるアクティビティの完全修飾クラス名です。
2078
2079
2080
2081
2082    </li>
2083</ol>
2084<p>
2085    <code>&lt;ContactsAccountType&gt;</code> 要素については、<a href="#SocialStreamAcctType">&lt;ContactsAccountType&gt; 要素</a>で詳しく説明しています。
2086
2087</p>
2088<p>
2089    受け取るインテントには、ユーザーがクリックしたアイテムまたは写真のコンテンツ URI が格納されます。
2090    テキスト アイテムと写真とで異なるアクティビティを使用するには、同じファイルで両方の属性を使用します。
2091</p>
2092<h4>ソーシャル ネットワーキング サービスの操作</h4>
2093<p>
2094    ユーザーは、連絡先をソーシャル ネットワーキング サービスに招待するのに、端末の連絡先アプリケーションを離れる必要はありません。
2095その代わりとして、連絡先をアクティビティのどれかに招待するインテントを端末の連絡先アプリケーションに送信させることができます。
2096これをセットアップする方法は次のとおりです。
2097</p>
2098<ol>
2099    <li>
2100        <code>contacts.xml</code> という名前のファイルをプロジェクトの <code>res/xml/</code> ディレクトリに作成します。
2101このファイルが既に存在する場合は、この手順を省略できます。
2102    </li>
2103    <li>
2104        このファイルに要素 <code>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</code> を追加します。
2105
2106        この要素が既に存在する場合は、この手順を省略できます。
2107    </li>
2108    <li>
2109        次の属性を追加します。
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        <code><em>activityclass</em></code> 値は、インテントを受信するアクティビティの完全修飾クラス名です。
2117<code><em>invite_action_label</em></code> 値は、端末の連絡先アプリケーションの [<strong>Add Connection</strong>] メニューに表示される文字列です。
2118
2119
2120    </li>
2121</ol>
2122<p class="note">
2123    <strong>注:</strong> <code>ContactsSource</code> は廃止されたタグ名で、<code>ContactsAccountType</code> に置き換わっています。
2124
2125</p>
2126<h3 id="ContactsFile">contacts.xml リファレンス</h3>
2127<p>
2128    ファイル <code>contacts.xml</code> には、同期アダプタやアプリケーションと連絡先アプリケーションや連絡先プロバイダとのやり取りを管理する XML 要素が含まれています。
2129これらの要素について、以降のセクションで説明します。
2130
2131</p>
2132<h4 id="SocialStreamAcctType">&lt;ContactsAccountType&gt; 要素</h4>
2133<p>
2134    <code>&lt;ContactsAccountType&gt;</code> 要素は、アプリケーションと連絡先アプリケーションとのやり取りを管理します。
2135構文は次のとおりです。
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>含まれているファイル:</strong>
2150</p>
2151<p>
2152    <code>res/xml/contacts.xml</code>
2153</p>
2154<p>
2155    <strong>含めることのできる要素:</strong>
2156</p>
2157<p>
2158    <strong><code>&lt;ContactsDataKind&gt;</code></strong>
2159</p>
2160<p>
2161    <strong>説明:</strong>
2162</p>
2163<p>
2164    ユーザーが連絡先の 1 人をソーシャル ネットワーキングに招待できるようにしたり、ソーシャル ネットワーキング ストリームのどれかがアップデートされたらユーザーに通知したりするための、Android コンポーネントや UI ラベルを宣言します。
2165
2166
2167</p>
2168<p>
2169    属性プレフィックス <code>android:</code> は、<code>&lt;ContactsAccountType&gt;</code> の属性に必須ではないことに注目してください。
2170
2171</p>
2172<p>
2173    <strong>属性:</strong>
2174</p>
2175<dl>
2176    <dt>{@code inviteContactActivity}</dt>
2177    <dd>
2178        ユーザーが端末の連絡先アプリケーションで [<strong>Add Connection</strong>] を選択したときに起動する、アプリケーション内のアクティビティの完全修飾クラス名。
2179
2180
2181    </dd>
2182    <dt>{@code inviteContactActionLabel}</dt>
2183    <dd>
2184        [<strong>Add Connection</strong>] メニューで、{@code inviteContactActivity} に指定されたアクティビティ用に表示されるテキスト。
2185
2186        たとえば、文字列「Follow in my network」を指定できます。このラベルには文字列リソース ID を使用できます。
2187
2188    </dd>
2189    <dt>{@code viewContactNotifyService}</dt>
2190    <dd>
2191        ユーザーが連絡先を表示したときに通知を受け取ることになる、独自アプリケーション内のサービスの完全修飾クラス名。
2192この通知は端末の連絡先アプリケーションによって送信されます。これを使用することで、アプリケーションはデータ処理の多い操作を必要になるまで延期できます。
2193
2194たとえば、アプリケーションはこの通知への対応として、連絡先の高解像度写真と直近のソーシャル ストリーム アイテムを読み込んで表示できます。
2195
2196この機能について詳しくは、<a href="#SocialStreamInteraction">ソーシャル ストリーム操作</a>で説明しています。
2197<code>NotifierService.java</code> ファイルに指定された通知サービスの例は、<a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">SampleSyncAdapter</a> サンプル アプリケーションにあります。
2198
2199
2200
2201    </dd>
2202    <dt>{@code viewGroupActivity}</dt>
2203    <dd>
2204        グループ情報を表示できる、独自アプリケーション内のアクティビティの完全修飾クラス名。
2205ユーザーが端末の連絡先アプリケーションでグループラベルをタップすると、このアクティビティの UI が表示されます。
2206
2207    </dd>
2208    <dt>{@code viewGroupActionLabel}</dt>
2209    <dd>
2210        ユーザーがアプリケーションでグループを表示できるようにする UI コントロールに対し、連絡先アプリケーションが表示するラベル。
2211
2212        <p>
2213            たとえば、端末に Google+ アプリケーションをインストールし、Google+ を連絡先アプリケーションと同期すると、Google+ のサークルが連絡先アプリケーションの [<strong>グループ</strong>] タブにグループとして表示されます。
2214
2215Google+ サークルのどれかをクリックすると、そのサークルに所属する人が「グループ」として表示されます。
2216表示の最上部に、Google+ アイコンが表示されます。それをクリックすると、制御が Google+ アプリに移ります。連絡先アプリケーションはこれを {@code viewGroupActivity} を使用して行い、Google+ アイコンを {@code viewGroupActionLabel} の値として使用します。
2217
2218
2219
2220
2221        </p>
2222        <p>
2223            この属性には、文字列リソース ID を使用できます。
2224        </p>
2225    </dd>
2226    <dt>{@code viewStreamItemActivity}</dt>
2227    <dd>
2228        ユーザーが未加工連絡先のストリーム アイテムをタップしたときに端末の連絡先アプリケーションが起動する、独自アプリケーション内のアクティビティの完全修飾クラス名。
2229
2230    </dd>
2231    <dt>{@code viewStreamItemPhotoActivity}</dt>
2232    <dd>
2233        ユーザーが未加工連絡先のストリーム アイテムで写真をタップしたときに端末の連絡先アプリケーションが起動する、独自アプリケーション内のアクティビティの完全修飾クラス名。
2234
2235
2236    </dd>
2237</dl>
2238<h4 id="SocialStreamDataKind">&lt;ContactsDataKind&gt; 要素</h4>
2239<p>
2240    <code>&lt;ContactsDataKind&gt;</code> 要素は、連絡先アプリケーションにおける独自アプリケーションのカスタムデータ行の表示を管理します。構文は次のとおりです。
2241
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>含まれているファイル:</strong>
2252</p>
2253<code>&lt;ContactsAccountType&gt;</code>
2254<p>
2255    <strong>説明:</strong>
2256</p>
2257<p>
2258    この要素は、カスタムデータ行のコンテンツを未加工連絡先の詳細の一部として連絡先アプリケーションに表示させるために使用します。
2259<code>&lt;ContactsAccountType&gt;</code> の各 <code>&lt;ContactsDataKind&gt;</code> 子要素は、同期アダプタが {@link android.provider.ContactsContract.Data} テーブルに追加するカスタムデータ行のタイプを表します。
2260
2261使用するカスタム MIME タイプごとに <code>&lt;ContactsDataKind&gt;</code> 要素を 1 つ追加します。
2262データを表示しないカスタムデータ行がある場合は、この要素を追加する必要はありません。
2263
2264</p>
2265<p>
2266    <strong>属性:</strong>
2267</p>
2268<dl>
2269    <dt>{@code android:mimeType}</dt>
2270    <dd>
2271        {@link android.provider.ContactsContract.Data} テーブルに含まれるカスタムデータ行のどれかに定義したカスタム MIME タイプ。
2272たとえば、値 <code>vnd.android.cursor.item/vnd.example.locationstatus</code> は、連絡先の最新の場所情報を記録するデータ行のためのカスタム MIME タイプということが考えられます。
2273
2274
2275    </dd>
2276    <dt>{@code android:icon}</dt>
2277    <dd>
2278        連絡先アプリケーションがデータの隣に表示する Android <a href="{@docRoot}guide/topics/resources/drawable-resource.html">ドローアブル リソース</a>。
2279
2280そのデータが独自サービスからのものであることを示すのに使用します。
2281
2282    </dd>
2283    <dt>{@code android:summaryColumn}</dt>
2284    <dd>
2285        データ行から取得された 2 つの値で最初の列名。この値は、このデータ行のエントリの先頭行として表示されます。
2286この先頭行は、データの要約として使われることを狙ったものですが、省略可能です。
2287<a href="#detailColumn">android:detailColumn</a> もご覧ください。
2288
2289    </dd>
2290    <dt>{@code android:detailColumn}</dt>
2291    <dd>
2292        データ行から取得された 2 つの値で 2 番目の列名。この値は、このデータ行のエントリの 2 行目として表示されます。
2293{@code android:summaryColumn} もご覧ください。
2294
2295    </dd>
2296</dl>
2297<h2 id="AdditionalFeatures">連絡先プロバイダの追加機能</h2>
2298<p>
2299    ここまでのセクションで説明した主な機能の他に、連絡先プロバイダには連絡先データの作業用として次のような便利な機能が用意されています。
2300
2301</p>
2302    <ul>
2303       <li>連絡先グループ</li>
2304       <li>写真機能</li>
2305    </ul>
2306<h3 id="Groups">連絡先グループ</h3>
2307<p>
2308    連絡先プロバイダでは、オプションで、関連連絡先のコレクションを<strong>グループ</strong> データでラベル付けできます。
2309あるユーザー アカウントに関連付けられているサーバーがグループを管理する場合、そのアカウントのアカウント タイプ用の同期アダプタが、連絡先プロバイダとサーバーとの間でグループデータを転送する必要があります。
2310
2311ユーザーが新しい連絡先をサーバーに追加し、その連絡先を新しいグループに入れた場合、同期アダプタはその新しいグループを {@link android.provider.ContactsContract.Groups} テーブルに追加する必要があります。
2312
2313ある未加工連絡先が属するグループ(複数の場合あり)は、{@link android.provider.ContactsContract.Data} テーブルに、{@link android.provider.ContactsContract.CommonDataKinds.GroupMembership} MIME タイプを使用して格納されます。
2314
2315
2316</p>
2317<p>
2318    サーバーからの未加工連絡先データを連絡先プロバイダに追加する同期アダプタを設計している場合、グループを使用しないのであれば、連絡先プロバイダに対してデータが可視であることを通知する必要があります。
2319
2320ユーザーがアカウントを端末に追加したときに実行されるコード内で、連絡先プロバイダがそのアカウントに対して追加する {@link android.provider.ContactsContract.Settings} 行をアップデートします。
2321
2322この行で、{@link android.provider.ContactsContract.SettingsColumns#UNGROUPED_VISIBLE Settings.UNGROUPED_VISIBLE} 列の値を 1 に設定します。
2323
2324こうすると、連絡先プロバイダは、グループを使用していない場合でも、独自の連絡先データを可視にします。
2325
2326</p>
2327<h3 id="Photos">連絡先の写真</h3>
2328<p>
2329    {@link android.provider.ContactsContract.Data} テーブルは、写真を MIME タイプ {@link android.provider.ContactsContract.CommonDataKinds.Photo#CONTENT_ITEM_TYPE Photo.CONTENT_ITEM_TYPE} の行として格納します。
2330
2331この行の {@link android.provider.ContactsContract.RawContactsColumns#CONTACT_ID} 列は、それが属する未加工連絡先の {@code android.provider.BaseColumns#_ID} 列にリンクされます。
2332
2333
2334    クラス {@link android.provider.ContactsContract.Contacts.Photo} は、連絡先のプライマリ フォトの写真情報を格納する {@link android.provider.ContactsContract.Contacts} のサブテーブルを定義します。ここでプライマリ フォトとは、連絡先のプライマリ未加工連絡先のプライマリ フォトのことを示します。
2335
2336同様に、クラス {@link android.provider.ContactsContract.RawContacts.DisplayPhoto} は、未加工連絡先のプライマリ フォトに関する情報を含む {@link android.provider.ContactsContract.RawContacts} のサブテーブルを定義します。
2337
2338
2339
2340</p>
2341<p>
2342    {@link android.provider.ContactsContract.Contacts.Photo} と {@link android.provider.ContactsContract.RawContacts.DisplayPhoto} の参照ドキュメントには、写真情報の取得例が含まれています。
2343
2344未加工連絡先のプライマリ サムネイルを取得するための便利なクラスはありませんが、{@link android.provider.ContactsContract.Data} テーブルにクエリを送信して、未加工連絡先の {@code android.provider.BaseColumns#_ID}、{@link android.provider.ContactsContract.CommonDataKinds.Photo#CONTENT_ITEM_TYPE Photo.CONTENT_ITEM_TYPE}、{@link android.provider.ContactsContract.Data#IS_PRIMARY} 列を選んでその未加工連絡先のプライマリ フォト行を探すことができます。
2345
2346
2347
2348
2349
2350
2351</p>
2352<p>
2353    人のソーシャル ストリーム データにも写真が含まれていることがあります。その場合は {@code android.provider.ContactsContract.StreamItemPhotos} テーブルに格納されています。このテーブルについては、<a href="#StreamPhotos">ソーシャル ストリーム フォト</a>で詳しく説明しています
2354
2355
2356</p>
2357