1page.title=コンテンツ プロバイダの作成 2@jd:body 3<div id="qv-wrapper"> 4<div id="qv"> 5 6 7<h2>本書の内容</h2> 8<ol> 9 <li> 10 <a href="#DataStorage">データ ストレージを設計する</a> 11 </li> 12 <li> 13 <a href="#ContentURI">コンテンツ URI を設計する</a> 14 </li> 15 <li> 16 <a href="#ContentProvider">ContentProvider クラスを実装する</a> 17 <ol> 18 <li> 19 <a href="#RequiredAccess">必須メソッド</a> 20 </li> 21 <li> 22 <a href="#Query">query() メソッドを実装する</a> 23 </li> 24 <li> 25 <a href="#Insert">insert() メソッドを実装する</a> 26 </li> 27 <li> 28 <a href="#Delete">delete() メソッドを実装する</a> 29 </li> 30 <li> 31 <a href="#Update">update() メソッドを実装する</a> 32 </li> 33 <li> 34 <a href="#OnCreate">onCreate() メソッドを実装する</a> 35 </li> 36 </ol> 37 </li> 38 <li> 39 <a href="#MIMETypes">コンテンツ プロバイダ MIME を実装する</a> 40 <ol> 41 <li> 42 <a href="#TableMIMETypes">テーブルの MIME タイプ</a> 43 </li> 44 <li> 45 <a href="#FileMIMETypes">ファイルの MIME タイプ</a> 46 </li> 47 </ol> 48 </li> 49 <li> 50 <a href="#ContractClass">コントラクト クラスを実装する</a> 51 </li> 52 <li> 53 <a href="#Permissions">コンテンツ プロバイダ パーミッションを実装する</a> 54 </li> 55 <li> 56 <a href="#ProviderElement"><provider> 要素</a> 57 </li> 58 <li> 59 <a href="#Intents">インテントとデータアクセス</a> 60 </li> 61</ol> 62<h2>キークラス</h2> 63 <ol> 64 <li> 65 {@link android.content.ContentProvider} 66 </li> 67 <li> 68 {@link android.database.Cursor} 69 </li> 70 <li> 71 {@link android.net.Uri} 72 </li> 73 </ol> 74<h2>関連サンプル</h2> 75 <ol> 76 <li> 77 <a href="{@docRoot}resources/samples/NotePad/index.html"> 78 Note Pad のサンプル アプリケーション </a> 79 80 </li> 81 </ol> 82<h2>関連ドキュメント</h2> 83 <ol> 84 <li> 85 <a href="{@docRoot}guide/topics/providers/content-provider-basics.html"> 86 コンテンツ プロバイダの基本</a> 87 </li> 88 <li> 89 <a href="{@docRoot}guide/topics/providers/calendar-provider.html"> 90 カレンダー プロバイダ</a> 91 </li> 92 </ol> 93</div> 94</div> 95 96 97<p> 98 コンテンツ プロバイダは、データの中央リポジトリへのアクセスを管理します。Android アプリケーションでは 1 つ以上のクラスとしてプロバイダを実装し、要素をマニフェスト ファイルで実装します。 99 100いずれか 1 つのクラスがサブラス {@link android.content.ContentProvider} を実装します。これは、プロバイダと他のアプリケーションとの間のインターフェースになります。 101 102コンテンツ プロバイダは他のアプリケーションへのデータの提供を意図したものですが、ユーザーがプロバイダに管理されるデータを照会、修正するアクティビティをアプリケーション内に設定することもできます。 103 104 105</p> 106<p> 107 このトピックの残りの部分では、コンテンツ プロバイダと使用する API のリストをビルドするための基本的な手順を挙げていきます。 108 109</p> 110 111 112<!-- Before You Start Building --> 113<h2 id="BeforeYouStart">ビルドを開始する前に</h2> 114<p> 115 ビルドを開始する前に、次の操作を行います。 116</p> 117<ol> 118 <li> 119 <strong>コンテンツ プロバイダが必要かどうかを決定します</strong>。次のような機能を 1 つ以上提供する場合に、コンテンツ プロバイダをビルドする必要があります。 120 121 <ul> 122 <li>他のアプリケーションに複雑なデータやファイルを提供する。</li> 123 <li>アプリから他のアプリへの複雑なデータのコピーをユーザーに許可する。</li> 124 <li>検索フレームワークを使用してカスタムの検索候補を提供する。</li> 125 </ul> 126 <p> 127 完全に独自アプリケーション内だけで使用する場合は、SQLite データベースを使用するプロバイダは必要はありません。<em></em> 128 129 </p> 130 </li> 131 <li> 132 必要かどうかを決定していない場合は、プロバイダの詳細については「<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">コンテンツ プロバイダの基本</a>」のトピックをご覧ください。 133 134 135 </li> 136</ol> 137<p> 138 次に、以下の手順に従ってプロバイダをビルドします。 139</p> 140<ol> 141 <li> 142 データの未処理のストレージを設計します。コンテンツ プロバイダは次の 2 つの方法でデータを提供します。 143 <dl> 144 <dt> 145 ファイルデータ 146 </dt> 147 <dd> 148 通常、写真、オーディオ、ビデオなどのファイルの形式となるデータです。 149ファイルはアプリケーションのプライベート スペースに格納します。 150ファイルに対する別のアプリケーションからの要求に応じて、プロバイダからファイルへのハンドルが提供されます。 151 152 </dd> 153 <dt> 154 「構造化」データ 155 </dt> 156 <dd> 157 通常、データベース、配列、類似の構造の形式となるデータです。 158 テーブルの行と列に互換性を持つ形式でデータが格納されます。行は、担当者や在庫にあるアイテムなどのエンティティを表します。 159列は、担当者の名前やアイテムの価格などの、エンティティの一部のデータを表します。 160一般的にこのタイプのデータは SQLite データベースに格納しますが、任意のタイプの永続ストレージを使用できます。 161 162Android システムで使用できるストレージ タイプの詳細は、<a href="#DataStorage">データ ストレージを設計する</a>をご覧ください。 163 164 165 </dd> 166 </dl> 167 </li> 168 <li> 169 {@link android.content.ContentProvider} クラスの具体的な実装とそれに必要なメソッドを定義します。 170このクラスは、データと Android システムのそれ以外の部分とのインターフェースとなります。 171このクラスの詳細は、<a href="#ContentProvider">ContentProvider クラスを実装する</a>セクションをご覧ください。 172 173 </li> 174 <li> 175 プロバイダの認証局の文字列、コンテンツ URI、列名を定義します。プロバイダのアプリケーションでインテントを処理する場合は、インテント アクション、エクストラ データ、フラグも定義します。 176 177さらに、データにアクセスするアプリケーションに必要なパーミッションも定義します。 178これらの値はすべて定数として個別のコントラクト クラスに定義するようにします。そうしておくと、後で他のデベロッパーに対してこのクラスを公開できます。 179コンテンツ URI の詳細は、<a href="#ContentURI">コンテンツ URI を設計する</a>セクションをご覧ください。 180 181 182 インテントの使用に関する詳細については、<a href="#Intents">インテントとデータアクセス</a>セクションをご覧ください。 183 184 </li> 185 <li> 186 サンプルデータや、プロバイダとクラウドベースのデータの間でデータを同期する {@link android.content.AbstractThreadedSyncAdapter} の実装などの、その他のオプション部分を追加します。 187 188 189 </li> 190</ol> 191 192 193<!-- Designing Data Storage --> 194<h2 id="DataStorage">データ ストレージを設計する</h2> 195<p> 196 コンテンツ プロバイダは、構造化された形式で保存されているデータへのインターフェースです。インターフェースを作成する前に、データの格納方法を決定しておく必要があります。 197データは任意の形式で保存でき、必要に応じてデータの読み取りと書き込みを行うためのインターフェースを設計できます。 198 199</p> 200<p> 201 Android には、次のように、いくつかのデータ格納テクノロジーがあります。 202</p> 203<ul> 204 <li> 205 Android システムには、Android の独自のプロバイダがテーブル指向のデータを格納するために使用する、SQLite データベース API があります。 206{@link android.database.sqlite.SQLiteOpenHelper} クラスを使用すると、データベースを作成できます。また、{@link android.database.sqlite.SQLiteDatabase} クラスは、データベースにアクセスするための基本クラスです。 207 208 209 210 <p> 211 リポジトリを実装するのに、データベースを使用する必要がありません。外部的には、プロバイダはリレーショナル データベースに似た一連のテーブルとして表示されますが、プロバイダの内部実装をそのような形式にする必要はありません。 212 213 214 </p> 215 </li> 216 <li> 217 ファイルデータを格納するために、Android にはファイル指向のさまざまな API があります。 218 ファイル ストレージの詳細は、「<a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a>」トピックをご覧ください。 219音楽やビデオのようにメディア関連のデータを提供するプロバイダを設計する場合は、テーブルデータとファイルを組み合わせるプロバイダを作成できます。 220 221 222 </li> 223 <li> 224 ネットワーク ベースのデータで作業する場合は、{@link java.net} と {@link android.net} のクラスを使用します。 225また、ネットワーク ベースをデータベースなどのローカル データストアに同期させ、データをテーブルやファイルとして提供することもできます。 226 227 <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">サンプル同期アダプタ</a>のサンプル アプリケーションでは、このタイプの同期のデモを紹介しています。 228 229 </li> 230</ul> 231<h3 id="DataDesign"> 232 データ設計上の考慮事項 233</h3> 234<p> 235 次に、プロバイダのデータ構造を設計する際のヒントを示します。 236</p> 237<ul> 238 <li> 239 テーブルデータには、プロバイダが各行の一意の数値として保持する「プライマリキー」列が常に必要です。 240この値を使用すると、行を他のテーブルの関連する行にリンクできます(「外部キー」として使用)。 241この列には任意の名前を設定できますが、プロバイダ クエリの結果を {@link android.widget.ListView} にリンクさせるには、取得する列のいずれかの名前が <code>_ID</code> になっている必要があるため、{@link android.provider.BaseColumns#_ID BaseColumns._ID} を使用することをお勧めします。 242 243 244 245 246 </li> 247 <li> 248 ビットマップ画像やサイズが非常に大きなその他のファイル指向のデータを提供する場合は、テーブルにデータを直接格納するのではなく、データをファイルに格納し、データを間接的に提供します。 249 250その場合、データにアクセスするには、{@link android.content.ContentResolver} ファイル メソッドの使用が必要であることをプロバイダのユーザーに通知する必要があります。 251 252 </li> 253 <li> 254 サイズや構造が異なるデータを格納するには、バイナリ ラージ オブジェクト(BLOB)データタイプを使用します。 255たとえば、<a href="http://code.google.com/p/protobuf">Protocol Buffer</a> や <a href="http://www.json.org">JSON 構造</a>を格納するには、BLOB 列を使用します。 256 257 258 <p> 259 さらに、BLOB を使用してスキーマに依存しないテーブルを実装できます。<em></em>このタイプのテーブルでは、プライマリキー列、MIME タイプ列、1 つ以上の汎用列を BLOB として定義します。 260 261BLOB 列内のデータの内容は、MIME タイプ列の値によって示されます。 262これにより、同じテーブルにさまざまな行タイプを格納できます。 263連絡先プロバイダの「データ」テーブル {@link android.provider.ContactsContract.Data} は、スキーマに依存しないテーブルの例です。 264 265 266 </p> 267 </li> 268</ul> 269<!-- Designing Content URIs --> 270<h2 id="ContentURI">コンテンツ URI を設計する</h2> 271<p> 272 <strong>コンテンツ URI</strong> は、プロバイダのデータを特定する URI です。コンテンツ URI には、プロバイダ全体の識別名(<strong>認証局</strong>)とテーブルやファイルをポイントする名前(<strong>パス</strong>)が含まれます。 273 274オプションの ID 部分は、テーブル内の個々の行を指します。 275{@link android.content.ContentProvider} のそれぞれのデータアクセス メソッドは引数としてコンテンツ URI を使用します。これにより、アクセスするテーブル、行、ファイルを決定できます。 276 277 278</p> 279<p> 280 コンテンツ URI の基本については、「<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">コンテンツ プロバイダの基本</a>」トピックをご覧ください。 281 282 283</p> 284<h3>認証局を設計する</h3> 285<p> 286 通常、プロバイダは、Android 内部の名前として使用される認証局を 1 つ持ちます。他のプロバイダとの競合を避けるためには、(逆に)プロバイダの認証局の基礎としてインターネット ドメインの所有権を使用する必要があります。 287 288この推奨事項は Android パッケージ名にもあてはまるため、プロバイダを含むパッケージの名前の拡張子として、プロバイダの認証局を定義できます。 289 290たとえば、Android パッケージ名が <code>com.example.<appname></code> の場合、プロバイダに認証局 <code>com.example.<appname>.provider</code> を付与する必要があります。 291 292 293</p> 294<h3>パス構造を設計する</h3> 295<p> 296 デベロッパーは通常、個々のテーブルを指すパスを末尾に追加して認証局からコンテンツ URI を作成します。 297たとえば、<em>table1</em> と <em>table2</em> の 2 つのテーブルがある場合、前の例の認証局を組み合わせてコンテンツ URI <code>com.example.<appname>.provider/table1</code> と <code>com.example.<appname>.provider/table2</code> を作成します。 298 299 300 301パスは 1 つのセグメントに限定されず、パスの各レベルにテーブルを作成する必要はありません。 302 303</p> 304<h3>コンテンツ URI ID を処理する</h3> 305<p> 306 慣例として、URI の末尾にある行の ID 値を持つコンテンツ URI を受け取ることで、プロバイダはテーブル内の 1 つの行へのアクセスを提供します。さらに、慣例として、プロバイダは ID 値をテーブルの <code>_ID</code> 列とマッチングし、一致する行に対して要求されたアクセスを実行します。 307 308 309 310</p> 311<p> 312 この慣例により、プロバイダにアクセスするアプリの一般的なパターンを簡単に設計できます。アプリはプロバイダにクエリを実行し、{@link android.widget.CursorAdapter} を使用して、取得した {@link android.database.Cursor} を {@link android.widget.ListView} に表示します。 313 314 315 {@link android.widget.CursorAdapter} の定義には、{@link android.database.Cursor} のいずれかの列を <code>_ID</code> に設定する必要があります 316 317</p> 318<p> 319 その後、ユーザーはデータの確認や修正のために、表示された行のいずれかを UI から選択します。 320アプリは {@link android.widget.ListView} を返す {@link android.database.Cursor} から対応する行を取得し、この行の <code>_ID</code> 値を取得し、その値をコンテンツ URI の末尾に追加して、プロバイダにアクセス要求を送ります。 321 322その後、プロバイダは、ユーザーが選択した行にクエリや修正を実行します。 323 324</p> 325<h3>コンテンツ URI パターン</h3> 326<p> 327 受け取ったコンテンツ URI に対するアクションを簡単に選択できるように、プロバイダ API には {@link android.content.UriMatcher} という便利なクラスが用意されています。このクラスはコンテンツ URI 「パターン」を正数値にマッピングします。 328 329この正数値を <code>switch</code> 文で使用することで、特定のパターンに一致する 1 つ以上のコンテンツ URI に目的のアクションを選択できます。 330 331</p> 332<p> 333 コンテンツ URI パターンは、次のワイルドカード文字を使用するコンテンツ URI に一致します。 334</p> 335 <ul> 336 <li> 337 <strong><code>*</code>:</strong> 任意の長さの任意の有効な文字で構成される文字列に一致します。 338 </li> 339 <li> 340 <strong><code>#</code>:</strong> 任意の長さの任意の数字で構成される文字列に一致します。 341 </li> 342 </ul> 343<p> 344 コンテンツ URI 処理の設計とコーディングの例として、テーブルを指す次のコンテンツ URI を認識する認証局 <code>com.example.app.provider</code> を持つプロバイダを考えてみます。 345 346 347</p> 348<ul> 349 <li> 350 <code>content://com.example.app.provider/table1</code>: <code>table1</code> という名前のテーブル。 351 </li> 352 <li> 353 <code>content://com.example.app.provider/table2/dataset1</code>: <code>dataset1</code> という名前のテーブル。 354 355 </li> 356 <li> 357 <code>content://com.example.app.provider/table2/dataset2</code>: <code>dataset2</code> という名前のテーブル。 358 359 </li> 360 <li> 361 <code>content://com.example.app.provider/table3</code>: <code>table3</code> という名前のテーブル。 362 </li> 363</ul> 364<p> 365 さらに、行 ID が末尾に追加されていると、プロバイダではこれらのコンテンツ URI が認識されます。たとえば、<code>table3</code> の <code>1</code> で特定される行は <code>content://com.example.app.provider/table3/1</code> になります。 366 367 368</p> 369<p> 370 次のようなコンテンツ URI パターンを使用できます。 371</p> 372<dl> 373 <dt> 374 <code>content://com.example.app.provider/*</code> 375 </dt> 376 <dd> 377 プロバイダの任意のコンテンツ URI に一致します。 378 </dd> 379 <dt> 380 <code>content://com.example.app.provider/table2/*</code>: 381 </dt> 382 <dd> 383 テーブル <code>dataset1</code> と <code>dataset2</code> のコンテンツ URI に一致しますが、<code>table1</code> や <code>table3</code> のコンテンツ URI には一致しません。 384 385 386 </dd> 387 <dt> 388 <code>content://com.example.app.provider/table3/#</code>: <code>table3</code> の 1 つの行のコンテンツ URI に一致します。<code>6</code> で特定される行は <code>content://com.example.app.provider/table3/6</code> になります。 389 390 391 392 </dt> 393</dl> 394<p> 395 次のコード スニペットでは、{@link android.content.UriMatcher} のメソッドが機能する仕組みを示します。 396 このコードでは、テーブルにコンテンツ URI パターン <code>content://<authority>/<path></code> を使用し、1 つの行に <code>content://<authority>/<path>/<id></code> を使用することで、表全体の URI と 1 つの行の URI を異なる方法で処理します。 397 398 399 400</p> 401<p> 402 メソッド {@link android.content.UriMatcher#addURI(String, String, int) addURI()} は認証局とパスを正数値にマッピングします。 403メソッド {@link android.content.UriMatcher#match(Uri) 404 match()} は URI に正数値を返します。次のように、<code>switch</code> 文によって、クエリをテーブル全体に実行するか、1 つのレコードに実行するかが決まります。 405 406</p> 407<pre class="prettyprint"> 408public class ExampleProvider extends ContentProvider { 409... 410 // Creates a UriMatcher object. 411 private static final UriMatcher sUriMatcher; 412... 413 /* 414 * The calls to addURI() go here, for all of the content URI patterns that the provider 415 * should recognize. For this snippet, only the calls for table 3 are shown. 416 */ 417... 418 /* 419 * Sets the integer value for multiple rows in table 3 to 1. Notice that no wildcard is used 420 * in the path 421 */ 422 sUriMatcher.addURI("com.example.app.provider", "table3", 1); 423 424 /* 425 * Sets the code for a single row to 2. In this case, the "#" wildcard is 426 * used. "content://com.example.app.provider/table3/3" matches, but 427 * "content://com.example.app.provider/table3 doesn't. 428 */ 429 sUriMatcher.addURI("com.example.app.provider", "table3/#", 2); 430... 431 // Implements ContentProvider.query() 432 public Cursor query( 433 Uri uri, 434 String[] projection, 435 String selection, 436 String[] selectionArgs, 437 String sortOrder) { 438... 439 /* 440 * Choose the table to query and a sort order based on the code returned for the incoming 441 * URI. Here, too, only the statements for table 3 are shown. 442 */ 443 switch (sUriMatcher.match(uri)) { 444 445 446 // If the incoming URI was for all of table3 447 case 1: 448 449 if (TextUtils.isEmpty(sortOrder)) sortOrder = "_ID ASC"; 450 break; 451 452 // If the incoming URI was for a single row 453 case 2: 454 455 /* 456 * Because this URI was for a single row, the _ID value part is 457 * present. Get the last path segment from the URI; this is the _ID value. 458 * Then, append the value to the WHERE clause for the query 459 */ 460 selection = selection + "_ID = " uri.getLastPathSegment(); 461 break; 462 463 default: 464 ... 465 // If the URI is not recognized, you should do some error handling here. 466 } 467 // call the code to actually do the query 468 } 469</pre> 470<p> 471 別の {@link android.content.ContentUris} には、コンテンツ URI の一部である <code>id</code> で作業するための便利なメソッドが備わっています。 472クラス {@link android.net.Uri} と {@link android.net.Uri.Builder} には、既存の {@link android.net.Uri} オブジェクトを解析して新しいオブジェクトをビルドするための便利なメソッドがあります。 473 474 475</p> 476 477<!-- Implementing the ContentProvider class --> 478<h2 id="ContentProvider">ContentProvider クラスを実装する</h2> 479<p> 480 {@link android.content.ContentProvider} インスタンスは、他のアプリケーションからの要求を処理することで、一連の構造化されたデータへのアクセスを管理します。 481どのような形式でアクセスする場合も、最終的には {@link android.content.ContentResolver} が呼び出されます。その後 {@link android.content.ContentProvider} の具象メソッドが呼び出され、アクセスを取得します。 482 483 484</p> 485<h3 id="RequiredAccess">必須メソッド</h3> 486<p> 487 抽象クラス {@link android.content.ContentProvider} は 6 つの抽象メソッドを定義しますが、これらのメソッドは独自の具象サブクラスの一部として実装する必要があります。 488次のように、{@link android.content.ContentProvider#onCreate() onCreate()} を除くこれらのメソッドは、コンテンツ プロバイダへのアクセスを試みるクライアント アプリケーションによって呼び出されます。 489 490 491</p> 492<dl> 493 <dt> 494 {@link android.content.ContentProvider#query(Uri, String[], String, String[], String) 495 query()} 496 </dt> 497 <dd> 498 プロバイダからデータを取得します。引数を使って、クエリを実行するテーブル、返す行と列、結果の並び順を選択します。 499 500 データは {@link android.database.Cursor} オブジェクトとして返されます。 501 </dd> 502 <dt> 503 {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} 504 </dt> 505 <dd> 506 プロバイダに新しい行を挿入します。引数を使って、挿入先のテーブルを選択し、使用する列の値を取得します。 507新たに挿入した行のコンテンツ URI が返されます。 508 509 </dd> 510 <dt> 511 {@link android.content.ContentProvider#update(Uri, ContentValues, String, String[]) 512 update()} 513 </dt> 514 <dd> 515 プロバイダ内の既存の行を更新します。引数を使って、更新するテーブルと行を選び、更新された列の値を取得します。 516更新された行の数が返されます。 517 </dd> 518 <dt> 519 {@link android.content.ContentProvider#delete(Uri, String, String[]) delete()} 520 </dt> 521 <dd> 522 プロバイダから行を削除します。引数を使って、削除するテーブルと行を選びます。 523削除された行の数が返されます。 524 </dd> 525 <dt> 526 {@link android.content.ContentProvider#getType(Uri) getType()} 527 </dt> 528 <dd> 529 コンテンツ URI に対応する MIME タイプを返します。このメソッドの詳細は、<a href="#MIMETypes">コンテンツ プロバイダ MIME を実装する</a>セクションをご覧ください。 530 531 </dd> 532 <dt> 533 {@link android.content.ContentProvider#onCreate() onCreate()} 534 </dt> 535 <dd> 536 プロバイダを初期化します。プロバイダが作成されると、Android システムがこのメソッドを即座に呼び出します。 537{@link android.content.ContentResolver} オブジェクトがアクセスを試みるまでは、プロバイダは作成されません。 538 539 </dd> 540</dl> 541<p> 542 これらのメソッドが持つ署名は、同じ名前の {@link android.content.ContentResolver} メソッドの署名と同じになります。 543 544</p> 545<p> 546 これらのメソッドを実装する場合は、次の点を考慮する必要があります。 547</p> 548<ul> 549 <li> 550 {@link android.content.ContentProvider#onCreate() onCreate()} を除くこれらのすべてのメソッドは、複数のスレッドを使用して同時に呼び出すことができるため、スレッドに対応した設定にする必要があります。 551複数のスレッドの詳細は、<a href="{@docRoot}guide/components/processes-and-threads.html">プロセスとスレッド</a>をご覧ください。 552 553 554 555 </li> 556 <li> 557 {@link android.content.ContentProvider#onCreate() 558 onCreate()} では冗長な操作は行わないようにします。本当に必要になるまでは、タスクの初期化は行わないようにします。 559 詳細は、<a href="#OnCreate">onCreate() メソッドを実装する</a>をご覧ください。 560 561 </li> 562 <li> 563 これのメソッドの実装は必須ですが、コードでは予測されたデータタイプを返す以外の操作は必要ありません。 564たとえば、他のアプリケーションが一部のテーブルにデータを挿入できないように設定するとします。 565その場合、{@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} への呼び出しを無視して 0 を返します。 566 567 568 </li> 569</ul> 570<h3 id="Query">query() メソッドを実装する</h3> 571<p> 572 {@link android.content.ContentProvider#query(Uri, String[], String, String[], String) 573 ContentProvider.query()} メソッドは {@link android.database.Cursor} オブジェクトを返す必要があります。失敗した場合は、{@link java.lang.Exception} をスローします。 574 575SQLite データベースをデータストレージとして使用する場合は、{@link android.database.sqlite.SQLiteDatabase} クラスのいずれかの <code>query()</code> メソッドが返す {@link android.database.Cursor} を返します。 576 577 578 クエリがどの行にも一致しない場合は、{@link android.database.Cursor#getCount()} メソッドが 0 を返す {@link android.database.Cursor} インスタンスを返す必要があります。 579 580 クエリプロセス中にエラーが発生した場合にのみ <code>null</code> を返します。 581</p> 582<p> 583 SQLite データベースをデータストレージとして使用しない場合は、{@link android.database.Cursor} クラスのいずれかの具象サブクラスを使用します。 584たとえば、{@link android.database.MatrixCursor} クラスは、各行が {@link java.lang.Object} の配列となるカーソルを実装します。 585このクラスでは、{@link android.database.MatrixCursor#addRow(Object[]) addRow()} を使って新しい行を追加します。 586 587</p> 588<p> 589 Android システムは、プロセスの境界をまたいで {@link java.lang.Exception} を送信できるように設定する必要があることにご注意ください。 590Android では、クエリエラーを処理するのに便利な、次の例外を送信できます。 591 592</p> 593<ul> 594 <li> 595 {@link java.lang.IllegalArgumentException}(プロバイダが無効なコンテンツ URI を受け取った場合にこの例外をスローするように選択できます) 596 597 </li> 598 <li> 599 {@link java.lang.NullPointerException} 600 </li> 601</ul> 602<h3 id="Insert">insert() メソッドを実装する</h3> 603<p> 604 {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} メソッドは、{@link android.content.ContentValues} 引数の値を使用して、適切なテーブルに新しい行を追加します。 605 606列名が {@link android.content.ContentValues} 引数にない場合は、プロバイダ コードがデータベース スキーマのいずれかで、デフォルト値を設定できます。 607 608 609</p> 610<p> 611 このメソッドは新しい行のコンテンツ URI を返します。作成するには、{@link android.content.ContentUris#withAppendedId(Uri, long) withAppendedId()} を使用して、新しい行の <code>_ID</code>(または他のプライマリキー)の値をテーブルのコンテンツ URI の末尾に追加します。 612 613 614</p> 615<h3 id="Delete">delete() メソッドを実装する</h3> 616<p> 617 {@link android.content.ContentProvider#delete(Uri, String, String[]) delete()} メソッドでは、データストレージから行を物理的に削除する必要はありません。 618プロバイダで同期アダプタを使用する場合は、行全体を削除するのではなく、削除された行に「削除」フラグを付けるようにします。 619 620同期アダプタは削除された行を探して、プロバイダから削除される前に、サーバーから行を削除できます。 621 622</p> 623<h3 id="Update">update() メソッドを実装する</h3> 624<p> 625 {@link android.content.ContentProvider#update(Uri, ContentValues, String, String[]) 626 update()} メソッドは {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} が使用するのと同じ {@link android.content.ContentValues} 引数、{@link android.content.ContentProvider#delete(Uri, String, String[]) delete()} と {@link android.content.ContentProvider#query(Uri, String[], String, String[], String) 627 ContentProvider.query()} が使用するのと同じ <code>selection</code> と <code>selectionArgs</code> 引数を使用します。 628 629 630 631これにより、これらのメソッド間でコードを再利用できます。 632</p> 633<h3 id="OnCreate">onCreate() メソッドを実装する</h3> 634<p> 635 Android システムはプロバイダを起動する際に {@link android.content.ContentProvider#onCreate() 636 onCreate()} を呼び出します。このメソッドでは迅速に実行できる初期化タスクのみを実行するようにし、プロバイダが実際にデータの要求を受け取るまでは、データベースの作成とデータロードを保留します。 637 638{@link android.content.ContentProvider#onCreate() onCreate()} で冗長なタスクを行う場合は、プロバイダの起動が遅くなります。 639 640同様に、プロバイダから他のアプリケーションへの応答も遅くなります。 641 642</p> 643<p> 644 たとえば、SQLite データベースを使用すると、{@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()} に {@link android.database.sqlite.SQLiteOpenHelper} オブジェクトを作成し、データベースを初めて開くときに SQL テーブルを作成できます。 645 646 647この操作を簡単にするために、{@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase 648 getWritableDatabase()} を初めて呼び出すときには、{@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase) 649 SQLiteOpenHelper.onCreate()} メソッドが自動的に呼び出されます。 650 651 652</p> 653<p> 654 次の 2 つのスニペットは、{@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()} と {@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase) 655 SQLiteOpenHelper.onCreate()} との間のやり取りを表しています。 656 657最初のスニペットは {@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()} の実装です。 658 659</p> 660<pre class="prettyprint"> 661public class ExampleProvider extends ContentProvider 662 663 /* 664 * Defines a handle to the database helper object. The MainDatabaseHelper class is defined 665 * in a following snippet. 666 */ 667 private MainDatabaseHelper mOpenHelper; 668 669 // Defines the database name 670 private static final String DBNAME = "mydb"; 671 672 // Holds the database object 673 private SQLiteDatabase db; 674 675 public boolean onCreate() { 676 677 /* 678 * Creates a new helper object. This method always returns quickly. 679 * Notice that the database itself isn't created or opened 680 * until SQLiteOpenHelper.getWritableDatabase is called 681 */ 682 mOpenHelper = new MainDatabaseHelper( 683 getContext(), // the application context 684 DBNAME, // the name of the database) 685 null, // uses the default SQLite cursor 686 1 // the version number 687 ); 688 689 return true; 690 } 691 692 ... 693 694 // Implements the provider's insert method 695 public Cursor insert(Uri uri, ContentValues values) { 696 // Insert code here to determine which table to open, handle error-checking, and so forth 697 698 ... 699 700 /* 701 * Gets a writeable database. This will trigger its creation if it doesn't already exist. 702 * 703 */ 704 db = mOpenHelper.getWritableDatabase(); 705 } 706} 707</pre> 708<p> 709 次のスニペットは {@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase) 710 SQLiteOpenHelper.onCreate()} の実装であり、ヘルパークラスを含みます。 711 712</p> 713<pre class="prettyprint"> 714... 715// A string that defines the SQL statement for creating a table 716private static final String SQL_CREATE_MAIN = "CREATE TABLE " + 717 "main " + // Table's name 718 "(" + // The columns in the table 719 " _ID INTEGER PRIMARY KEY, " + 720 " WORD TEXT" 721 " FREQUENCY INTEGER " + 722 " LOCALE TEXT )"; 723... 724/** 725 * Helper class that actually creates and manages the provider's underlying data repository. 726 */ 727protected static final class MainDatabaseHelper extends SQLiteOpenHelper { 728 729 /* 730 * Instantiates an open helper for the provider's SQLite data repository 731 * Do not do database creation and upgrade here. 732 */ 733 MainDatabaseHelper(Context context) { 734 super(context, DBNAME, null, 1); 735 } 736 737 /* 738 * Creates the data repository. This is called when the provider attempts to open the 739 * repository and SQLite reports that it doesn't exist. 740 */ 741 public void onCreate(SQLiteDatabase db) { 742 743 // Creates the main table 744 db.execSQL(SQL_CREATE_MAIN); 745 } 746} 747</pre> 748 749 750<!-- Implementing ContentProvider MIME Types --> 751<h2 id="MIMETypes">ContentProvider MIME タイプを実装する</h2> 752<p> 753 {@link android.content.ContentProvider} クラスには、MIME タイプを返すための次の 2 つのクラスがあります。 754</p> 755<dl> 756 <dt> 757 {@link android.content.ContentProvider#getType(Uri) getType()} 758 </dt> 759 <dd> 760 任意のプロバイダに実装する必要がある必須メソッドの 1 つです。 761 </dd> 762 <dt> 763 {@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()} 764 </dt> 765 <dd> 766 ファイルを提供するプロバイダの場合に、実装が考えられるメソッドです。 767 </dd> 768</dl> 769<h3 id="TableMIMETypes">テーブルの MIME タイプ</h3> 770<p> 771 {@link android.content.ContentProvider#getType(Uri) getType()} メソッドは、MIME 形式で {@link java.lang.String} を返します。これは、コンテンツ URI 引数によって返されるデータのタイプを表します。 772 773{@link android.net.Uri} 引数には特定の URI ではなくパターンを指定することもできます。この場合、パターンに一致するコンテンツ URI に関連付けられているデータのタイプを返します。 774 775 776</p> 777<p> 778 テキスト、HTML、JPEG といった一般的なタイプのデータの場合、{@link android.content.ContentProvider#getType(Uri) getType()} では該当するデータの標準的な MIME タイプを返す必要があります。 779 780利用できるこれらの標準的なタイプの詳細なリストは、「<a href="http://www.iana.org/assignments/media-types/index.htm">IANA MIME Media Types</a>」のウェブサイトをご覧ください。 781 782 783</p> 784<p> 785 テーブル データの 1 つ以上の行を指すコンテンツ URI の場合、{@link android.content.ContentProvider#getType(Uri) getType()} は、Android のベンダー固有の MIME 形式で MIME タイプを返す必要があります。 786 787 788</p> 789<ul> 790 <li> 791 タイプ部分: <code>vnd</code> 792 </li> 793 <li> 794 サブタイプ部分: 795 <ul> 796 <li> 797 URI パターンが 1 つの行の場合: <code>android.cursor.<strong>item</strong>/</code> 798 </li> 799 <li> 800 URI パターンが複数の行の場合: <code>android.cursor.<strong>dir</strong>/</code> 801 </li> 802 </ul> 803 </li> 804 <li> 805 プロバイダ固有の部分: <code>vnd.<name></code>.<code><type></code> 806 <p> 807 <code><name></code> と <code><type></code> を指定します。 808 <code><name></code> の値はグローバルに一意の値とし、<code><type></code> の値は対応する URI パターンに一意のものとする必要があります。 809 810<code><name></code> には、企業名や、アプリケーションの Android パッケージ名の一部を使うことをお勧めします。 811<code><type></code> には、URI に関連付けられているテーブルを特定する文字列を使うことをお勧めします。 812 813 814 </p> 815 816 </li> 817</ul> 818<p> 819 たとえば、プロバイダの認証局が <code>com.example.app.provider</code> の場合、テーブル名は <code>table1</code> となり、<code>table1</code> の複数行の MIME タイプは次のようになります。 820 821 822</p> 823<pre> 824vnd.android.cursor.<strong>dir</strong>/vnd.com.example.provider.table1 825</pre> 826<p> 827 <code>table1</code> の 1 つの行の場合は、MIME タイプは次のようになります。 828</p> 829<pre> 830vnd.android.cursor.<strong>item</strong>/vnd.com.example.provider.table1 831</pre> 832<h3 id="FileMIMETypes">ファイルの MIME タイプ</h3> 833<p> 834 ファイルを提供するプロバイダの場合は、{@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()} を実装します。 835 836 このメソッドは、プロバイダが特定のコンテンツ URI に対して返すことができるファイルの MIME タイプの {@link java.lang.String} 配列を返します。クライアントで処理する MIME タイプのみを返すには、MIME タイプフィルタ引数によって、提供する MIME タイプをフィルタする必要があります。 837 838 839</p> 840<p> 841 たとえば、写真画像を <code>.jpg</code>、<code>.png</code>、<code>.gif</code> 形式で提供するプロバイダについて考えてみます。 842 843 アプリケーションが {@link android.content.ContentResolver#getStreamTypes(Uri, String) 844 ContentResolver.getStreamTypes()} をフィルタ文字列 <code>image/*</code> (何らかの形式の「画像」)で呼び出す場合、{@link android.content.ContentProvider#getStreamTypes(Uri, String) 845 ContentProvider.getStreamTypes()} メソッドは次のような配列を返します。 846 847 848</p> 849<pre> 850{ "image/jpeg", "image/png", "image/gif"} 851</pre> 852<p> 853 アプリの対象が <code>.jpg</code> ファイルのみであり、アプリが {@link android.content.ContentResolver#getStreamTypes(Uri, String) 854 ContentResolver.getStreamTypes()} をフィルタ文字列 <code>*\/jpeg</code> で呼び出す場合、{@link android.content.ContentProvider#getStreamTypes(Uri, String) 855 ContentProvider.getStreamTypes()} は次の項目を返します。 856 857 858<pre> 859{"image/jpeg"} 860</pre> 861<p> 862 プロバイダが、フィルタ文字列で要求した MIME タイプを提供していない場合、{@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()} は <code>null</code> を返します。 863 864 865</p> 866 867 868<!-- Implementing a Contract Class --> 869<h2 id="ContractClass">コントラクト クラスを実装する</h2> 870<p> 871 コントラクト クラスは <code>public final</code> クラスであり、URI、列名、MIME タイプ、プロバイダに関連するその他のメタデータを含みます。 872このクラスは、URI や列名などの実際の値が変更された場合にも、プロバイダに正しくアクセスできることを保証することで、プロバイダとその他のアプリケーションとの間にコントラクトを構築します。 873 874 875 876</p> 877<p> 878 さらに、通常、コントラクト クラスではその定数にニーモニック名が設定されているため、デベロッパーが列名や URI に誤った値を使用しにくいようになっています。 879クラスであるため、Javadoc ドキュメントを含めることができます。 880Eclipse などの統合型開発環境では、コントラクト クラスから定数名が自動的に設定され、定数の Javadoc が表示されます。 881 882 883</p> 884<p> 885 デベロッパーはアプリケーションからコントラクト クラスのクラスファイルにアクセスできませんが、提供する <code>.jar</code> ファイルからクラスファイルをアプリケーションに静的にコンパイルできます。 886 887</p> 888<p> 889 {@link android.provider.ContactsContract} クラスとそのネストされたクラスは、コントラクト クラスの例です。 890 891</p> 892<h2 id="Permissions">コンテンツ プロバイダ パーミッションを実装する</h2> 893<p> 894 Android システムのあらゆる領域に対するパーミッションとクラスについては、「<a href="{@docRoot}guide/topics/security/security.html">セキュリティとパーミッション</a>」トピックをご覧ください。 895 896 また、トピック「<a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a>」にも、ストレージのさまざまなタイプに有効なセキュリティとパーミッションについて記載されています。 897 898 重要な点をまとめると次のようになります。 899</p> 900<ul> 901 <li> 902 デフォルトでは、端末の内部ストレージに格納されるデータファイルは、アプリケーションとプロバイダでのみ使用できます。 903 904 </li> 905 <li> 906 作成する {@link android.database.sqlite.SQLiteDatabase} データベースは、自分のアプリケーションとプロバイダにのみ公開されます。 907 908 </li> 909 <li> 910 デフォルトでは、外部ストレージに保存するデータファイルはパブリックとなり、誰もが読み取ることができます。<em></em><em></em> 911他のアプリケーションは別の API 呼び出しを使用してファイルの読み取りと書き込みを実行できるため、コンテンツ プロバイダで外部ストレージにあるファイルへのアクセスは制限できません。 912 913 </li> 914 <li> 915 端末の内部ストレージにあるファイルや SQLite データベースを開いたり作成したりするメソッド呼び出しは、他のすべてのアプリケーションに読み取りと書き込みの両方のアクセスを付与してしまう可能性があります。 916内部ファイルやデータベースをプロバイダのリポジトリとして使用する場合に、「誰でも読み取り可能」や「誰でも書き込み可能」なアクセスを付与してしまうと、マニフェストで設定したプロバイダのパーミッションでデータを保護できなくなってしまいます。 917 918 919内部ストレージのファイルとデータベースへのデフォルトのアクセスは「プライベート」になっているため、プロバイダのリポジトリの場合はこの設定を変更しないでください。 920 921 </li> 922</ul> 923<p> 924 コンテンツ プロバイダ パーミッションを使用してデータへのアクセスを制御する場合は、内部ファイル、SQLite データベース、「クラウド」(リモート サーバーなど)にデータを格納し、ファイルやデータベースを自分のアプリケーションにのみ公開するように設定します。 925 926 927</p> 928<h3>パーミッションを実装する</h3> 929<p> 930 デフォルトではプロバイダにはパーミッションが設定されていないため、基礎となるデータがプライベートに設定されている場合でも、すべてのアプリケーションは自分のプロバイダからの読み取りとプロバイダへの書き込みを実行できます。 931これを変更するには、<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 932 <provider></a></code> 要素の属性や子要素を使用して、マニフェスト ファイルでプロバイダのパーミッションを設定します。 933 934プロバイダ全体に適用するパーミッションを設定することもできますし、特定のテーブル、特定のレコード、これら 3 つすべてに適用するパーミッションを設定することもできます。 935 936</p> 937<p> 938 マニフェスト ファイルで 1 つ以上の <code><a href="{@docRoot}guide/topics/manifest/permission-element.html"> 939 <permission></a></code> 要素を使用して、プロバイダのパーミッションを定義します。 940自分のプロバイダに独自のパーミッションを作成するには、<code><a href="{@docRoot}guide/topics/manifest/permission-element.html#nm"> 941 android:name</a></code> 属性に Java スタイルのスコーピングを使用します 942 943たとえば、読み取りパーミッションの名前を <code>com.example.app.provider.permission.READ_PROVIDER</code> とします。 944 945 946</p> 947<p> 948 次のリストは、プロバイダ パーミッションの範囲を示しています。プロバイダ全体に適用するパーミッションから始まり、より詳細な範囲のものになっています。 949 950 より広い範囲を持つパーミッションよりも、範囲が限定されるパーミッションの方が優先されます。 951</p> 952<dl> 953 <dt> 954 プロバイダ レベルで 1 つの読み取りと書き込みのパーミッション 955 </dt> 956 <dd> 957 1 つのパーミッションでプロバイダ全体の読み取りと書き込みのアクセスの両方を制御します。<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 958 <provider></a></code> 要素の <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn"> 959 android:permission</a></code> 属性で指定します。 960 961 962 </dd> 963 <dt> 964 プロバイダ レベルで別々の読み取りと書き込みパーミッション 965 </dt> 966 <dd> 967 プロバイダ全体の読み取りパーミッションと書き込みパーミッションです。これらのパーミッションは <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 968 <provider></a></code> 要素の <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#rprmsn"> 969 android:readPermission</a></code> 属性と <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#wprmsn"> 970 android:writePermission</a></code> 属性で指定します。 971 972 973これらは、<code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn"> 974 android:permission</a></code> で要求するパーミッションよりも優先されます。 975 976 </dd> 977 <dt> 978 パスレベルのパーミッション 979 </dt> 980 <dd> 981 プロバイダのコンテンツ URI の読み取り、書き込み、読み取り / 書き込みパーミッションです。<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 982 <provider></a></code> 要素の <code><a href="{@docRoot}guide/topics/manifest/path-permission-element.html"> 983 <path-permission></a></code> 子要素を使用して、制御対象の各 URI を指定します。 984 985 986指定する各コンテンツ URI に対して、読み取り / 書き込みパーミッション、読み取りパーミッション、書き込みパーミッション、3 つすべてを指定できます。 987読み取りパーミッションと書き込みパーミッションは、読み取り / 書き込みパーミッションに優先します。 988また、パスレベルのパーミッションはプロバイダ レベルのパーミッションに優先します。 989 990 </dd> 991 <dt> 992 一時的なパーミッション 993 </dt> 994 <dd> 995 アプリケーションへの一時的なアクセスを付与するパーミッション レベルです。アプリケーションに通常必要とするパーミッションが付与されていない場合でも付与できます。 996一時的なアクセス機能により、アプリケーションのマニフェストに必要なパーミッションの数を減らせます。 997 998一時的なパーミッションを有効にすると、プロバイダへの「永続的な」パーミッションを必要とするアプリケーションのみが、継続的にすべてのデータにアクセスできます。 999 1000 1001 <p> 1002 プロバイダからの写真の添付ファイルを外部の画像ビューワ アプリケーションで表示する場合に、メール プロバイダとアプリに実装するパーミッションを考えてみます。 1003 1004パーミッションを要求しなくても、画像ビューワに必要なアクセスを付与するには、写真のコンテンツ URI に一時的なパーミッションを設定します。 1005ユーザーが写真を表示しようとしたときに、アプリから写真のコンテンツ URI とパーミッション フラグを含むインテントを画像ビューワに送信するようにメール アプリを設計します。 1006 1007ビューワにプロバイダの通常の読み取りパーミッションが付与されていない場合でも、画像ビューワはメール プロバイダにクエリを実行して写真を取得します。 1008 1009 1010 </p> 1011 <p> 1012 一時的なパーミッションを有効にするには、<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 1013 <provider></a></code> 要素の <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn"> 1014 android:grantUriPermissions</a></code> 属性を設定するか、1 つ以上の <code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html"> 1015 <grant-uri-permission></a></code> 子要素を <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 1016 <provider></a></code> 要素に追加します。 1017 1018 1019 1020一時的なパーミッションを使用する場合、プロバイダからのコンテンツ URI のサポートを削除したときは常に {@link android.content.Context#revokeUriPermission(Uri, int) 1021 Context.revokeUriPermission()} を呼び出す必要があります。そうすると、コンテンツ URI が一時的なパーミッションに関連付けられます。 1022 1023 1024 </p> 1025 <p> 1026 属性の値によって、プロバイダへのアクセスレベルが決まります。 1027 属性を <code>true</code> に設定すると、システムによってプロバイダ全体への一時的なパーミッションが付与されます。このパーミッションは、プロバイダ レベルやパスレベルのパーミッションで必要になるその他のパーミッションよりも優先されます。 1028 1029 1030 </p> 1031 <p> 1032 このフラグを <code>false</code> に設定する場合は、<code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html"> 1033 <grant-uri-permission></a></code> 子要素を <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 1034 <provider></a></code> 要素に追加する必要があります。 1035 1036それぞれの子要素は、一時的なアクセスが付与される 1 つ以上のコンテンツ URI を指定します。 1037 1038 </p> 1039 <p> 1040 一時的なアクセスをアプリケーションに委任するには、インテントに {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION} フラグか {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION} フラグ、またはその両方を含める必要があります。 1041 1042これらは、{@link android.content.Intent#setFlags(int) setFlags()} メソッドで設定します。 1043 1044 </p> 1045 <p> 1046 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn"> 1047 android:grantUriPermissions</a></code> 属性がない場合は、<code>false</code> であると仮定されます。 1048 1049 </p> 1050 </dd> 1051</dl> 1052 1053 1054 1055<!-- The Provider Element --> 1056<h2 id="ProviderElement"><provider> 要素</h2> 1057<p> 1058 {@link android.app.Activity} コンポーネントや {@link android.app.Service} コンポーネントと同様に、<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 1059 <provider></a></code> 要素を使用して {@link android.content.ContentProvider} のサブクラスをアプリケーションのマニフェスト ファイルに定義する必要があります。 1060 1061 1062Android システムは要素から次の情報を取得します。 1063 1064<dl> 1065 <dt> 1066 認証局(<a href="{@docRoot}guide/topics/manifest/provider-element.html#auth">{@code 1067 android:authorities}</a>) 1068 1069 </dt> 1070 <dd> 1071 システム内のプロバイダ全体を特定する識別名です。この属性の詳細は、<a href="#ContentURI">コンテンツ URI を設計する</a>セクションをご覧ください。 1072 1073 1074 </dd> 1075 <dt> 1076 プロバイダ クラス名(<code> 1077<a href="{@docRoot}guide/topics/manifest/provider-element.html#nm">android:name</a> 1078 </code>) 1079 1080 </dt> 1081 <dd> 1082 {@link android.content.ContentProvider} を実装するクラスです。このクラスの詳細は、<a href="#ContentProvider">ContentProvider クラスを実装する</a>セクションをご覧ください。 1083 1084 1085 </dd> 1086 <dt> 1087 パーミッション 1088 </dt> 1089 <dd> 1090 他のアプリケーションがプロバイダのデータにアクセスするのに必要なパーミッションを指定する属性です。 1091 1092 <ul> 1093 <li> 1094 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn"> 1095 android:grantUriPermssions</a></code>: 一時的なパーミッションのフラグです。 1096 </li> 1097 <li> 1098 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn"> 1099 android:permission</a></code>: 1 つのプロバイダ全体の読み取り / 書き込みパーミッションです。 1100 </li> 1101 <li> 1102 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#rprmsn"> 1103 android:readPermission</a></code>: プロバイダ全体の読み取りパーミッションです。 1104 </li> 1105 <li> 1106 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#wprmsn"> 1107 android:writePermission</a></code>: プロバイダ全体の書き込みパーミッションです。 1108 </li> 1109 </ul> 1110 <p> 1111 パーミッションとそれに対応する属性の詳細は、<a href="#Permissions">コンテンツ プロバイダ パーミッションを実装する</a>セクションをご覧ください。 1112 1113 1114 </p> 1115 </dd> 1116 <dt> 1117 起動と制御の属性 1118 </dt> 1119 <dd> 1120 これらの属性は、Android システムの起動方法とそのタイミング、プロバイダのプロセスの特性、その他の実行時の設定を決定します。 1121 1122 <ul> 1123 <li> 1124 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#enabled"> 1125 android:enabled</a></code>: システムにプロバイダの起動を許可するフラグです。 1126 </li> 1127 <li> 1128 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#exported"> 1129 android:exported</a></code>: 他のアプリケーションにこのプロバイダの使用を許可するフラグです。 1130 </li> 1131 <li> 1132 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#init"> 1133 android:initOrder</a></code>: 同じプロセス内の他のプロバイダに対して、このプロバイダを起動する順番です。 1134 1135 </li> 1136 <li> 1137 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#multi"> 1138 android:multiProcess</a></code>: システムに呼び出しクライアントと同じプロセスでのプロバイダの開始を許可するフラグです。 1139 1140 </li> 1141 <li> 1142 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#proc"> 1143 android:process</a></code>: プロバイダを実行するプロセスの名前です。 1144 1145 </li> 1146 <li> 1147 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#sync"> 1148 android:syncable</a></code>: プロバイダのデータをサーバー上のデータと同期することを示すフラグです。 1149 1150 </li> 1151 </ul> 1152 <p> 1153 属性に関する詳細は、開発ガイドの <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 1154 <provider></a></code> 要素に関するトピックに記載されています。 1155 1156 1157 </p> 1158 </dd> 1159 <dt> 1160 情報に関する属性 1161 </dt> 1162 <dd> 1163 プロバイダのオプションのアイコンとラベルです。 1164 <ul> 1165 <li> 1166 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#icon"> 1167 android:icon</a></code>: プロバイダのアイコンを含むドローアブル リソースです。 1168 [設定] > [アプリ] > [すべて] にあるアプリのリストのプロバイダラベルの横に表示されるアイコンです。<em></em><em></em><em></em> 1169 1170 </li> 1171 <li> 1172 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#label"> 1173 android:label</a></code>: プロバイダ、データ、その両方を説明する、情報ラベルです。 1174[設定] > [アプリ] > [すべて] にあるアプリのリストのプロバイダラベルの横に表示されるアイコンです。<em></em><em></em><em></em> 1175 1176 </li> 1177 </ul> 1178 <p> 1179 属性に関する詳細は、開発ガイドの <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 1180 <provider></a></code> 要素に関するトピックに記載されています。 1181 1182 </p> 1183 </dd> 1184</dl> 1185 1186<!-- Intent Access --> 1187<h2 id="Intents">インテントとデータアクセス</h2> 1188<p> 1189 {@link android.content.Intent} を使用すると、アプリケーションはコンテンツ プロバイダに間接的にアクセスできます。 1190 アプリケーションは、{@link android.content.ContentResolver} や {@link android.content.ContentProvider} のメソッドを呼び出しません。 1191その代わりに、アクティビティを起動するインテントを送信します。これは通常、プロバイダ独自のアプリケーションの一部となっています。 1192対象のアクティビティは UI のデータの取得と表示を担当します。インテントのアクションに応じて、対象のアクティビティにより、ユーザーにプロバイダのデータの修正を求めるメッセージが表示されることがあります。 1193 1194 1195 さらに、インテントには、対象のアクティビティが UI に表示する「エクストラ」データが含まれることがあります。ユーザーは使用前に、このデータを変更してプロバイダのデータを修正することもできます。 1196 1197 1198</p> 1199<p> 1200 1201</p> 1202<p> 1203 インテント アクセスを使用して、データの整合性を保証できます。プロバイダのデータの挿入、更新、削除は、厳格に定義されたビジネス ロジックによって規定されることがあります。 1204この場合、他のアプリケーションにデータを直接修正できるように許可すると、無効なデータが発生することがあります。 1205 1206デベロッパーがインテント アクセスを使用する場合は、すべての操作を完全に文書化します。 1207 コードを使用してデータを修正するよりも、独自のアプリケーションの UI を使用したインテント アクセスの方が優れている理由を説明します。 1208 1209</p> 1210<p> 1211 プロバイダのデータを修正するための受信インテントの処理は、その他のインテントの処理と同じです。 1212インテントの使用についての詳細は、「<a href="{@docRoot}guide/components/intents-filters.html">インテントとインテント フィルタ</a>」をご覧ください。 1213 1214</p> 1215