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 <uses-permission></a></code> 要素を使用して <code><uses-permission android:name="android.permission.READ_CONTACTS"></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 <uses-permission></a></code> 要素を使用して <code><uses-permission android:name="android.permission.WRITE_CONTACTS"></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@Override 886public Loader<Cursor> onCreateLoader(int id, Bundle args) { 887 888 /* 889 * Sets the columns to retrieve. 890 * RAW_CONTACT_ID is included to identify the raw contact associated with the data row. 891 * DATA1 contains the first column in the data row (usually the most important one). 892 * MIMETYPE indicates the type of data in the data row. 893 */ 894 String[] projection = 895 { 896 ContactsContract.Contacts.Entity.RAW_CONTACT_ID, 897 ContactsContract.Contacts.Entity.DATA1, 898 ContactsContract.Contacts.Entity.MIMETYPE 899 }; 900 901 /* 902 * Sorts the retrieved cursor by raw contact id, to keep all data rows for a single raw 903 * contact collated together. 904 */ 905 String sortOrder = 906 ContactsContract.Contacts.Entity.RAW_CONTACT_ID + 907 " ASC"; 908 909 /* 910 * Returns a new CursorLoader. The arguments are similar to 911 * ContentResolver.query(), except for the Context argument, which supplies the location of 912 * the ContentResolver to use. 913 */ 914 return new CursorLoader( 915 getApplicationContext(), // The activity's context 916 mContactUri, // The entity content URI for a single contact 917 projection, // The columns to retrieve 918 null, // Retrieve all the raw contacts and their data rows. 919 null, // 920 sortOrder); // Sort by the raw contact ID. 921} 922</pre> 923<p> 924 読み込みが完了すると、{@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<ContentProviderOperation> ops = 1070 new ArrayList<ContentProviderOperation>(); 1071 1072 /* 1073 * Creates a new raw contact with its account type (server type) and account name 1074 * (user's account). Remember that the display name is not stored in this row, but in a 1075 * StructuredName data row. No other data is required. 1076 */ 1077 ContentProviderOperation.Builder op = 1078 ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) 1079 .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType()) 1080 .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName()); 1081 1082 // Builds the operation and adds it to the array of operations 1083 ops.add(op.build()); 1084</pre> 1085<p> 1086 次に、表示名、電話、メールのデータ行を作成します。 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<Cursor> loader, Cursor cursor) { 1274 1275 // Gets the raw contact's _ID and VERSION values 1276 mRawContactID = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID)); 1277 mVersion = cursor.getInt(cursor.getColumnIndex(SyncColumns.VERSION)); 1278} 1279 1280... 1281 1282// Sets up a Uri for the assert operation 1283Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, mRawContactID); 1284 1285// Creates a builder for the assert operation 1286ContentProviderOperation.Builder assertOp = ContentProviderOperation.netAssertQuery(rawContactUri); 1287 1288// Adds the assertions to the assert operation: checks the version and count of rows tested 1289assertOp.withValue(SyncColumns.VERSION, mVersion); 1290assertOp.withExpectedCount(1); 1291 1292// Creates an ArrayList to hold the ContentProviderOperation objects 1293ArrayList ops = new ArrayList<ContentProviderOperationg>; 1294 1295ops.add(assertOp.build()); 1296 1297// You would add the rest of your batch operations to "ops" here 1298 1299... 1300 1301// Applies the batch. If the assert fails, an Exception is thrown 1302try 1303 { 1304 ContentProviderResult[] results = 1305 getContentResolver().applyBatch(AUTHORITY, ops); 1306 1307 } catch (OperationApplicationException e) { 1308 1309 // Actions you want to take if the assert operation fails go here 1310 } 1311</pre> 1312<h3 id="Intents">インテントを使用した取得と変更</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<ContentValues> contactData = new ArrayList<ContentValues>(); 1497 1498 1499/* 1500 * Defines the raw contact row 1501 */ 1502 1503// Sets up the row as a ContentValues object 1504ContentValues rawContactRow = new ContentValues(); 1505 1506// Adds the account type and name to the row 1507rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType()); 1508rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName()); 1509 1510// Adds the row to the array 1511contactData.add(rawContactRow); 1512 1513/* 1514 * Sets up the phone number data row 1515 */ 1516 1517// Sets up the row as a ContentValues object 1518ContentValues phoneRow = new ContentValues(); 1519 1520// Specifies the MIME type for this data row (all data rows must be marked by their type) 1521phoneRow.put( 1522 ContactsContract.Data.MIMETYPE, 1523 ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE 1524); 1525 1526// Adds the phone number and its type to the row 1527phoneRow.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone); 1528 1529// Adds the row to the array 1530contactData.add(phoneRow); 1531 1532/* 1533 * Sets up the email data row 1534 */ 1535 1536// Sets up the row as a ContentValues object 1537ContentValues emailRow = new ContentValues(); 1538 1539// Specifies the MIME type for this data row (all data rows must be marked by their type) 1540emailRow.put( 1541 ContactsContract.Data.MIMETYPE, 1542 ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE 1543); 1544 1545// Adds the email address and its type to the row 1546emailRow.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email); 1547 1548// Adds the row to the array 1549contactData.add(emailRow); 1550 1551/* 1552 * Adds the array to the intent's extras. It must be a parcelable object in order to 1553 * travel between processes. The device's contacts app expects its key to be 1554 * Intents.Insert.DATA 1555 */ 1556insertIntent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contactData); 1557 1558// Send out the intent to start the device's contacts app in its add contact activity. 1559startActivity(insertIntent); 1560</pre> 1561<h3 id="DataIntegrity">データの整合性</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><ContactsAccountType></code> 要素と 1 つまたは複数の <code><ContactsDataKind></code> 子要素を含む <code>contacts.xml</code> ファイルを提供します。 1620 1621詳しくは、<a href="#SocialStreamDataKind"><code><ContactsDataKind> 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><<a href="{@docRoot}guide/topics/manifest/service-element.html">service</a>></code> 要素に定義されます。 1793 1794 1795これらの要素には、特定のデータをシステムに提供する次のような <code><<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>></code> 子要素が含まれます。 1796 1797 1798 1799 1800 <ul> 1801 <li> 1802 同期アダプタ サービス用の <code><<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>></code> 要素は、XML ファイル <code>res/xml/syncadapter.xml</code> を指します。 1803 1804 1805このファイルが、連絡先プロバイダと同期されるウェブサービスの URI と、そのウェブサービスで使用するアカウント タイプを指定します。 1806 1807 1808 </li> 1809 <li> 1810 <strong>省略可能:</strong> 認証システム用の <code><<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>></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><ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"></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><ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"></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><ContactsAccountType></code> 要素については、<a href="#SocialStreamAcctType"><ContactsAccountType> 要素</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><ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"></code> を追加します。 2105 2106 この要素が既に存在する場合は、この手順を省略できます。 2107 </li> 2108 <li> 2109 次の属性を追加します。 2110 <ul> 2111 <li><code>inviteContactActivity="<em>activityclass</em>"</code></li> 2112 <li> 2113 <code>inviteContactActionLabel="@string/<em>invite_action_label</em>"</code> 2114 </li> 2115 </ul> 2116 <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"><ContactsAccountType> 要素</h4> 2133<p> 2134 <code><ContactsAccountType></code> 要素は、アプリケーションと連絡先アプリケーションとのやり取りを管理します。 2135構文は次のとおりです。 2136</p> 2137<pre> 2138<ContactsAccountType 2139 xmlns:android="http://schemas.android.com/apk/res/android" 2140 inviteContactActivity="<em>activity_name</em>" 2141 inviteContactActionLabel="<em>invite_command_text</em>" 2142 viewContactNotifyService="<em>view_notify_service</em>" 2143 viewGroupActivity="<em>group_view_activity</em>" 2144 viewGroupActionLabel="<em>group_action_text</em>" 2145 viewStreamItemActivity="<em>viewstream_activity_name</em>" 2146 viewStreamItemPhotoActivity="<em>viewphotostream_activity_name</em>"> 2147</pre> 2148<p> 2149 <strong>含まれているファイル:</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><ContactsDataKind></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><ContactsAccountType></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"><ContactsDataKind> 要素</h4> 2239<p> 2240 <code><ContactsDataKind></code> 要素は、連絡先アプリケーションにおける独自アプリケーションのカスタムデータ行の表示を管理します。構文は次のとおりです。 2241 2242</p> 2243<pre> 2244<ContactsDataKind 2245 android:mimeType="<em>MIMEtype</em>" 2246 android:icon="<em>icon_resources</em>" 2247 android:summaryColumn="<em>column_name</em>" 2248 android:detailColumn="<em>column_name</em>"> 2249</pre> 2250<p> 2251 <strong>含まれているファイル:</strong> 2252</p> 2253<code><ContactsAccountType></code> 2254<p> 2255 <strong>説明:</strong> 2256</p> 2257<p> 2258 この要素は、カスタムデータ行のコンテンツを未加工連絡先の詳細の一部として連絡先アプリケーションに表示させるために使用します。 2259<code><ContactsAccountType></code> の各 <code><ContactsDataKind></code> 子要素は、同期アダプタが {@link android.provider.ContactsContract.Data} テーブルに追加するカスタムデータ行のタイプを表します。 2260 2261使用するカスタム MIME タイプごとに <code><ContactsDataKind></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